Joseph Hallenbeck


July 1, 2015

A Social Media Fast

Filed under: Journal — Joseph @ 6:58 pm

Flattr this!

I’m taking a quarter off from Social Media — namely Facebook, Reddit, Slashdot, Twitter, Hacker News. I would unplug entirely from the Internet, but considering the Internet is my job, I don’t think my employer would be too hot on the idea on
me attending sprint planning via post.

My reason for this is simple: my information channels are becoming rather siloed. Facebook curates my news feed such that it is just an RSS feed of
same two people over and over again. I don’t know why Facebook has decided that I want to hear every one of their posts and it isn’t that I don’t enjoy them, or share in your cultural opinions but I have a rather diverse and eclectic collection of Facebook friends and yet I do not hear a diverse collection of views. The hive mind of Reddit and Hacker News also curates it’s own content to follow a very narrow line of acceptable opinions.

I find myself concerned with how much of the pot of ideas that surround me are my own — come upon by reason and experience and how much is just the echo chamber of my silo. A self-selected confirmation bias just regurgitating and re-enforcing the same normality time and again.

So my idea is to spend the next three months avoiding any form of social media or curated feeds. Get away from the content pushers and get back to being a content puller. Go back to hunting down my own news, essays, and articles through relaxing dives into Google. Find some high quality bloggers to follow who aren’t just trying to push some product or spin up a lazy article on the controversy de jouer for some easy ad views. Get through my backlog of technology articles in my pocket waiting for me to peruse.

For those where this is the only way they know how to get a hold of me: I will still be available via Facebook messenger thanks to Pidgin and via GooglePlus since there really isn’t anything on GooglePlus anyways.

See you all in October.


April 13, 2015

Cookbook: Turkey Chili

Filed under: Cooking — Joseph @ 10:00 am

Flattr this!

Turkey Chili

My slow-cooking turkey chili recipe. Takes all day to make, but it’s worth it!

Ingredients

  • 1/4 Cup Butter
  • 1 Large White Onion (Diced)
  • 1-2 Strips of Bacon (Diced)
  • 2.5 lbs. Ground Turkey
  • 1-2 Tbsp. Tomato Paste
  • 1 28oz. Can of Diced Tomatoes
  • 1 28oz. Can of Diced Jalapenos
  • 1 16oz. Bottle of Amber Ale
  • 2 Cups Chicken Broth
  • 1/4 Cup Apple Cide Vinegar
  • 2 Cups Dried Beans

Spice Mix

  • 1 Tbsp. Garlic
  • 1/2 Cup Chili Powder
  • 1/4 Cup Cumin
  • 2 Tsp. Ceyenne Pepper
  • 1 Tbsp. Paprika
  • 1 Tbsp. Oregano
  • 2 Tbsp. Brown Sugar
  • Salt/Pepper to Taste

Turkey Chili

Directions

Soak beans overnight then drain.

Melt butter in a large soup pot along with diced bacon over medium-high heat. Add diced onion and saute for five minutes. Add Ground turkey and cook, turning frequently, until browned. Add tomato paste, dice tomatoes, dice jalapenos, amber ale, chicken broth and vinegar. Turn to high. Add spice mixture, adjusting to taste. When pot begins to boil, add dried beans and turn down to low. Simmer four hours.

Serve over baked potatoes with a generous helping of cheddar cheese and sour cream or just eat plain.


March 30, 2015

Photo Journal #12 Flame Giant & Lilies

Filed under: Photography — Tags: — Joseph @ 10:00 am

Flattr this!

Macro photos of the flowers Jess got me for Valentine’s day last month. A good chance for practicing macro stacking as well.

The Fire Giant

Model: Nikon D80 /w Nikon 200mm f/4.0 AF-S FX
Shutter: 1/25 sec
F-Stop: f/4.2
ISO: 320
Focal Length: 200mm
Lighting: None
Stack: 5

The Fire Giant

Model: Nikon D80 /w Nikon 200mm f/4.0 AF-S FX
Shutter: 1/13 sec
F-Stop: f/4.5
ISO: 320
Focal Length: 200mm
Lighting: None
Stack: 6

Fire Giant with Lilies

Model: Nikon D80 /w Nikon 200mm f/4.0 AF-S FX
Shutter: 1/25 sec
F-Stop: f/4.2
ISO: 320
Focal Length: 200mm
Lighting: None
Stack: 3


March 23, 2015

Trails: Wolf Creek [Winter]

Filed under: Outdoors — Tags: , , , , — Joseph @ 10:00 am

Flattr this!

Details

  • Location: Alpine, WY
  • Length: 1 mi (Winter)
  • Water Access: Yes (Winter)
  • Usage: Light (Winter)
  • Highlights: Limestone escarpments, pine forest cover
  • Safety Concerns: Winter avalanches, embankments too steep for safe winter hiking. River crossings.

Trail Map for Wolf Creek

In February, we found much of the nearby trails around Jackson, WY either packed or simply closed off from excursions. This has become a recurring theme in Jackson and one that is getting rather tiresome. We turned to looking westward and in turn into the Snake River Range between Hoback and Alpine, WY.

The canyon is rather steep walled, but a number of drainages into the canyon have trailheads — Red Creek, Wolf Creek, and East Table Creek. The turn offs in the winter are plowed allowing for year-round access and most importantly they are outside of the winter range closures.

Directions

In our first venture we tried the Wolf Creek Trail which is located some 16 miles west of Hoback and before the Wolf Creek campground.

February Conditions

Steep embankments on Wolf Creek

We were unable to complete the trail in February. We got roughly one mile up the drainage with snow shoes before turning back. This was, in large part, due to the burn on the west side of the drainage. This leaves the landscape open for avalanches, of which there were many. A hiker with a more aggressive “mountaineering” shoe may make the trip, but our wide flat-lands snow shoes were insufficient.

The avalanches left large piles of breakdown crossing the trail. This required a great deal of scrambling over five-foot wide bricks of snow not unlike scrambling over cave breakdown. In other areas the snow bank was simply a steep, smooth layer of ice that slide down the hill into the river. In these instances it was difficult to get a sound perch as our snow shoes’s claws were not enough to keep us from sliding down hill.

The draw is rather pretty, featuring limestone escapements, pine forest, and a ready supply of water via Wolf Creek. The maps show that it is possible to ascend Wolf or Red mountain via this route. We shall try it again come spring or summer once the snow recedes enough to walk upon a flat trail.


March 16, 2015

Trails: Sweeney Ridge [Winter]

Filed under: Outdoors — Tags: , , , — Joseph @ 10:00 am

Flattr this!

Details

  • Location: Pinedale, WY
  • Length: 6 mi
  • Water Access: None
  • Usage: Moderate
  • Highlights: Spectacular view of the wind river range, Half Moon Lake and Pinedale
  • Safety Concerns: Steep embankments in areas

Sweeney Ridge Map

After venturing to Half Moon lake several times throughout February we decided to check out the cross country ski trails on top of the nearby ridge. We found these trails to be in much heavier use during the day time than aforementioned Half Moon, but for what they gave up in solitude we gained in views. Sweeney Road, an ungroomed cross country tail, is perhaps the most isolating and best for snow shoeing undisturbed with dogs.

Directions

View from Sweeney Ridge in February

Like Half Moon, Sweeney Road is accessed via the Fremont Lake road leaving Pinedale, WY. Proceed some ten miles up the road and passed the turn-off for Half Moon. The road is plowed up the resort and there are many pull offs for various groomed cross country skiing trails. The first pull off, however, is for Sweeney Road which is an ungroomed trail following a Forest Service road.

February Conditions

View from Sweeney Ridge in February

The groomed cross country ski trails appear to be under heavy use, however being ungroomed, Sweeney Road sees much more moderate usage. Furthermore, we found that many snow shoers appear to take the route for only some time before diverging upon their own paths. In our case we took a branch that looped out much closer to the ridge edge giving us a wonderful view of Half Moon lake, the wind river range, and the plains that spread out far below us to Pinedale.

If kept to the main trail the conditions are moderate and fairly easy going upon snow shoes. The diverging routes however can in places be rather steep and I imagine unsound if the snow top is icy and hardened. For ourselves the snow was ideal having a good layer of snow that we easily sunk into giving us a good grip upon the hillside.


March 9, 2015

Trails: Half Moon Lake [Winter]

Filed under: Outdoors — Tags: , , , — Joseph @ 10:00 am

Flattr this!

Details

  • Location: Pinedale, WY
  • Length: 3 mi (Winter)
  • Water Access: None (Winter)
  • Usage: Light (Winter)
  • Highlights: View of Half Moon Lake, Windriver Range
  • Safety Concerns: Care should be taken with ice depth. I have found no official ice-depth reports

Half Moon Trail Map

The Wind River Range in Pinedale, WY has a number of trails open for snow shoes or cross country skis year round. In our ventures south of Jackson, we have found the range rather open although range closures do exist in areas and many a Forest Service road turns into snowmobile track.

The paved road to Fremont lake, however, remains plowed and open year round giving easy access for a wintertime hiker.

Directions

Rowdy and Vicky are ready for the trail

Half Moon Lake lies south of Fremont Lake. Both can be accessed via Fremont Lake Road, paved route leaving Pinedale and heading north-east. This route is plowed year-round. Proceed some seven miles along the route until it diverges. A sign for the Half Moon resort is posted upon this fork. Turn right upon it and proceed down a gravel road. The fork is plowed, although poorly and I suspect only by chance of the private residences on the western lake shore. Signage indicts these private drives and are rather aggressive reading “Trespassers will be shot.”

Past the private drives is the campground, boat docks, and eventually parking for the resort. The latter being the furthest one can get in the winter to the trailhead itself.

February Conditions

Half Moon Lake from the shoreline

We returned to Half Moon lake several times in February. The lake is frozen, and although there are snowmobile tracks across it, the many weeks of above freezing weather gave us ill ease at walking out far from shore. Likewise, the warm weather left sections of the trail devoid of snow requiring us to remove snow shoes and embark upon foot only to find the snow returning in depths of four to five feet a hundred yards further.

The view is rather beautiful. The frozen lake a smooth expanse rising into a pine covered hill on the far side. The eastern shore and trail are devoid of trees giving it a highlands desert feel. The rocky soil covered in sage of
various types and much sign of elk and deer.


February 7, 2015

2014 In Review

Filed under: Journal — Joseph @ 1:35 pm

Flattr this!

It is that time of year again, time for my retrospective. A look back on last year’s goals and a reflection on what I would like out of this year. It may be a month late for New Year’s resolutions, but I do get to them eventually.

One thing that I started up last year was a much more rigorous interpretation of David Allen’s Getting Things Done. I used a similar process towards breaking down and getting to tasks in the past, but this last year was one where I focused much more on continuously revising my goals, recording what I got done, and asking myself what I needed to do next. Some time, I will get a series of essays put together to discuss my process.

Professional Achievements

2014 closed out with my last day at 44 Interactive, and I hope a permanent move away from the marketing side of web development and into the more fulfilling realm of application development as a Software Engineer with my new employer, Research Square out of Durham, NC. I am still remote, having moved from Ashton, ID up to Jackson, WY — a town much more my style and now working out of Spark, a nice co-working spot that has encouraged me to once more shed my outer humbug.

While working at 44 Interactive, I developed a bespoke shopping cart that saw itself launched on Dakota Golf and Warriors Never Giveup. This project implemented the entire workflow that user’s expect of a shopping cart: adding products, customizing product details, checkout, payment collection and processing through Authorize.Net or PayPal, and shipping.

A few fun features I developed was a reworking of the underlying models of our CMS to use the Eloquent ORM, integration with Composer and Bower for pulling in libraries, building out a re-occurring events module for calculating things like “occurs on every last Thursday of the month” or “repeat every Monday.” One showcase item is the HTML5 Canvas powered course tour on Dakota Golf whose administrative tools allow for drawing arbitrary polygons and detecting when a mouse enters a polygon.

In the brochure realm, I launched McDoctors, SDN Communications, Dakotastour, Wings of Thunder, Howeinc, and All-About-U Adoptions.

With my change of employers, I am hanging up my System Admin hat, which was a fun one to wear for a time. No more debugging package conflicts, no more reading PCI reports, or writing new rules for mod_sec. I do delight in the fact that I consolidated servers costs by 50% during my tenure and brought up time to 99.9%.

Continuous Development

I am committed to continuous professional development in my field. I do this via reading and writing blogs, reading technical manuals, as well as investigating topics in computer science that might only be orthogonal to my day-to-day life.

In the last year, I read Miracle Man Month and Code Complete. After a short affair in learning LateX last spring, I turned to devour every article and online book I could find on the Rust language and began following the language mailing list as well as subscribing to frameworks like Piston. I wanted to really make some open source contributions, but never quite found a niche where I could step in and help out.

After some consideration, I released the DropFramework and my TimeKeeper application onto Github. The first, I do not take seriously as anything more than a learning project and the latter is a really helpful tool that I use every day.

Oh, and those projects I promised last year? I started on a lot of them, then lost interest. Instead, I started Rusty Centipede — a Centipede clone using Rust.

Rainbow over Island Park, Viewed from Bishop Mt.

(more…)


October 13, 2014

DropFramwork

Filed under: Software Development — Tags: , , , — Joseph @ 6:00 pm

Flattr this!

This summer, I plunged into the depths of my back up drives and came up with some old projects that were growing some dust. Like most old projects, I find them, get excited. Decide to do a major revolutionary revamp, and ultimately just end up touching up some things and kicking them out the door. The DropFramework is one such thing. For a long time, I wanted to make my own micro-framework to compete with the likes of Slim or Silex. In the end though, I really feel that those two have the space of micro-frameworks very well covered. No one needs yet another PHP micro-framework with half-done ideas floating around. Still, I did want to show it off, so I polished it up a little bit and through it up on github. Below are my thoughts on “Yet Another PHP Microframework:”

Yet Another PHP Microframework

For all intensive purposes, you can consider this an abandoned project and I would not recommend anyone actually use this in production.

A few years ago when Code Igniter was still quite a hot thing and a lot of
servers were still running PHP 5.2, e.g. the “dark ages” before we got all the nice things that came along in PHP 5.3 it seemed to be quite the fashion for everyone to try their hand at writing their own framework.

This was my go at it.

You will find a lot of similarities with Code Igniter (since that is the framework I worked with at the time) and you might also find a lot of classes that look like they came straight out of PHP Objects, Patterns and Practice since that was my bible.

I wanted to do a few things in writing the DropFramework:

  1. I wanted to better understand the MVC pattern, the choices being made and how CI works.
  2. I wanted a framework that was small enough that I could read and understand every class in it.
  3. I wanted a framework with a very small footprint that worked by transforming HTTP requests into request objects / command objects. This allowed me to fire up multiple instances of the framework per HTTP request with the master application generating it’s own request objects that it would feed into it’s child instances and then construct a document out of the application responses from the children.
  4. I did not like at the time, and still do not like the major design patterns of a lot of ORM solutions which tend to treat the database as the authoritative model of the data. I rather turn this convention upside down: treat the database as just another form of user input. The model can then be constructed from any form of input — the database, an HTTP post, a file. The PHP object is then the authoritative source for how the data structure relates with other data. Any data coming into the model passes through a validation layer that translates it (or rejects it if it invalid).

Whether or not I succeeded at this items? I don’t think I would really know.

Version 0.4.0

The version of the framework that had been sitting on my hard disk for some time was 0.3.0. In deciding to release it I have done two major things:

  1. I created a simple example of the framework working. The code for this example is also up on github and a live version as well.
  2. I namespaced the entire framework and brought it into PSR-4 compliance allowing for installation via Composer and the use of the Composer autoloader. This defeats a lot of the purpose of the PHP 5.2 era frameworks which devoted a lot of their resources to locating and managing the loading of assets. This, of course, makes this no longer a PHP 5.2 compatible framework and probably even makes a lot of the framework look rather silly.

October 1, 2014

Centipede-RS Dev Log #2

Filed under: Journal,Software Development — Tags: , , — Joseph @ 5:00 pm

Flattr this!

Getting started with Piston can be a little daunted right now. Mostly this is because it’s a project that is still evolving and which has either little documentation or documentation that rapidly becomes wrong. A lot of games that I found made with Piston can no longer be compiled, a lot of example code needs various minor tweaks to get to compile, etc. That said, the two best items that I found where:

Getting Started

The first hurdle in getting Piston to work was getting the SDL2 and GLFW dependencies installed. Cargo does a great job of going out and grabbing everything else, but these two items require you to do it yourself. SDL2 was rather easy and the instructions for it can be found in the Getting Started tutorial (see above). GLFW was a bit more of a pain and I ended up going through a stack overflow question to get it working. If anything, I would just point to the Getting started tutorial to get the initial empty repository set up with cargo and all the dependencies in the Cargo.toml.

My Repository at this Point

At this point my repository looks like this. I began by setting up a new Piston project as detailed in the Getting Started tutorial and from there I copied the code from the piston image example. This was just a nice starting point to ensure that everything is working and that the Rust logo would appear in the window designated.

From there, I began working through the Piston-Mov-Square project and the Getting Started tutorials and religiously commenting every line of the code with what it does. This is just something I picked up in college and a good way to puzzle out foreign code. Even if the comment turns out to be wrong (like it happened in many cases for myself), it at least is a step in manually dealing with the code.

I played around for a while and after I felt confident in the code that I had, I began abstracting it into various data objects and getting down to work. Hopefully my puzzling with help someone else to understand this faster than I.

An Explanation of the Code

Loading Crates

// Load external crates provided via cargo.
extern crate graphics;
extern crate piston;
extern crate sdl2_game_window;
extern crate opengl_graphics;

// Texture is used for images; Gl for accessing OpenGL
use opengl_graphics::{
    Gl,  
};

// For creating a window
use sdl2_game_window::WindowSDL2;

// Stuff from piston.
use piston::{
    EventIterator,                  // Used for the game loop
    EventSettings,                  // Struct used for setting and updates
    WindowSettings,                 // Struct defines window config
    Render,                         // Render Evemt 
};

use piston::graphics::*;
use piston::shader_version::opengl;

We begin by loading all of our various library provided to us by the Piston developers and which we will use for getting our game window to appear on the screen. I have yet to figure out what the #![feature(globs)] lint actually does and if someone does know, I would love to find out since removing it causes everything to break. The rest of the code is just giving us access to various libraries that we will use latter on. I have tried to comment those libraries as best I could since it wasn’t entirely clear what does what.

Config and Main Entry Point

// Config options for the game.
struct GameConfig {
    title: String,
    window_height: u32,
    window_width: u32,
    updates_per_second: u64,
    max_frames_per_second: u64,
    tile_size: uint
}

// Entry point for our game.
fn main() {

    let config = GameConfig {
            title: "Centipede-RS".to_string(),
            window_height: 480,
            window_width: 800,
            updates_per_second: 120,
            max_frames_per_second: 60,
            tile_size: 32,
        };

    // Create and run new game.
    let mut game = Game::new( config );
    game.run();
}

If there is one thing that I know it’s to confine magic numbers. Let them sprout wherever you please and code maintenance becomes a mess. Hence, I have taken the various constants for our game and packaged them up into a GameConfig struct. Right now this struct defines the attributes of our window: title, height, width, frames per second, and tile size. I imagine that this structure will probably grow larger as we begin adding in actors, players, and assets. We will deal with that when the time comes.

I have also created a Game struct (more on it later). The game struct simple takes a GameConfig and returns an instance of itself. Calling run fires off our game loop which loops infinitely or until we kill the process. In essence the Game struct represents and handles the loop. We could leave this in main, but by turning it into a struct we have the option further down the line of moving it out into a module which would leave our main.rs file consisting only of loading Piston, setting the various config items and calling Game.run.

The Game Struct

// Represents the Game Loop
struct Game {
    config: GameConfig
}

impl Game {
    ...
}

I’ve seen this simply called App, but since we are making a game, I think it should be Game. The Game simply holds the game state and runs the game loop. Inside it, I have added several methods via impl: new, run, window, and render. New and run are our public methods which we have already seen. One takes a GameConfig and returns a Game. The other starts the game loop. The remaining methods are just there to run the internals of the loop itself. Let’s walk through each method:

// Returns a new game struct
pub fn new( config: GameConfig ) -> Game {                           

    // Return a new Game
    Game {
        config: config,
    }

}

Game.Run

This one is rather simple. It is a public function (pub fn) named new. We can access it via Game::new(). It takes a GameConfig and returns a Game whose config property is config. I am sure I am mixing a lot of OOP language here, but after years of working in the realm of PHP that’s just how I end up thinking.

// Run the game loop
pub fn run( &mut self ) {

    let mut window = self.window();        
    ...
}  

Run is a little messier it fires off our game loop. It takes a mutable copy of itself which allows us to access it on an instance of Game e.g. game.run(). The first line it calls is to a member function window():

// Returns a window.
fn window( &self ) -> WindowSDL2 {

    // Values for Window Creation
    let window_settings = WindowSettings {
            title: self.config.title.to_string(),
            size: [self.config.window_width, self.config.window_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 0,
        };

    // Create SDL Window
    WindowSDL2::new(
        opengl::OpenGL_3_2,
        window_settings
    )        
}

This is not a public function, thus when we turn Game into a module it will not be accessible outside of the module file. We are using this essentially as a hidden or private method on Game. The window function is accessible from inside a game object via self, e.g. self.window(). We really only need one window, so this method is only called once at the start of the run method. Window returns a WindowSDL2 which is our back-end we loaded way above at the start for managing our windows. This window takes a WindowSettings struct whose values we pull out of the GameConfig stored in our Game. Either way, it makes a new WindowSDL2 and passes it back to the run method. Now back to our second line of the run method:

// Get Gl
let ref mut gl = Gl::new( opengl::OpenGL_3_2 );

Now this took me a while to figure out. The call to Gl::new() must come after the creation of the WindowSDL2. In an earlier version of this I had the call to create GL after the call to create the Window. The code will compile fine if you create GL first and then the Window, but when you run it you will get a CreateShader error. I only solved this by stumbling upon an IRC log. Anyways, hold on to that gl variable since we’ll be passing it around a lot.

// Create Settings for Game loop
let event_settings = EventSettings {
    updates_per_second: self.config.updates_per_second,
    max_frames_per_second: self.config.max_frames_per_second,
};

Rather boring. We need to create and EventSettings object to pass into our game loop.

// For each e in Event Iterator (whose range is 0 to infinity) 
// e becomes a new Event by passing our window and event settings
for e in EventIterator::new(&mut window, &event_settings) {

    // If e is Render(args) do something, else return ()?
    match e {
        Render(args) => self.render( gl ),
        _ => {},
    } 
}

Here is the magic! The game loop. I really like how this works in Rust. Since iterators can go from 0 to infinite we take advantage of it. The EventIterator takes the window and event_settings variables we set up earlier and returns something (I don’t know what) which is put into e. We then do a match on e to see what was returned. Right now there are only two things that can match: a call to render the screen, or everything else. Looking at some of the example code, I do see that we can catch all different kinds of events — user input, calls to update the game state, etc. but for now we are just concerned with rendering the screen. So we get a render event (Render(args)) and we call our private method render via self.render and pass in our gl variable (I said we would be passing him around a lot).

Game.Render

// Render the game state to the screen.
fn render( &mut self, gl: &mut Gl ) { 
    let width = self.config.window_width;
    let height = self.config.window_height;

    // Get number of columns and rows.
    let tile_size = self.config.tile_size;        
    let num_cols = width as int / tile_size as int;
    let num_rows = height as int / tile_size as int;  
    ...
}

Render simply takes a mutable reference to Gl and paints to our screen. The first two lines just get the window_height and window_width out of our config since we will be using them a lot in this method. Since this is going to be a tiled game we need to know how many columns and rows of tiles we will be drawing. So I calculate that here by dividing the window’s height and width by the tile_size.

// Creates viewport at 0,0 with width and height of window.
gl.viewport(0, 0, width as i32, height as i32);

// graphics::context a new drawing context (think html5)
let c = Context::abs(width as f64, height as f64);

The next two lines in our render call do two important things. First we set our view port to start at the cordinates 0,0 and to extend to the width and height of our window. Second, we get a Context which I like to think as our virtual pen for drawing on our canvas. In fact, the first thing we do is fill the entire canvas with white:

c.rgb(1.0, 1.0, 1.0).draw(gl);

This takes an rgb (red, green, blue) value that sets each to a 100% (or white) and then draws this to our window by calling draw and passing in our old friend gl.

Now let’s have some fun. Just to show that we are indeed drawing on the window, let’s fill the window with 32×32 pixel tiles each one slightly reader than the last. The effect should look like this:

Screenshot of Centipede-RS at Dev-2

We begin by setting our starting red value:

let mut red = 0.01

This needs to be mutable since we will be adding to it with each iteration of our rows.

Second, we loop through each row and each column drawing a red square the size of our tiles:

// Fill screen with red one 32x32 tile at a time.
for row in range(0i, num_rows ) {

    red = red + 0.02;    
    let row_shift: f64 = row as f64 * tile_size as f64;

    for col in range(0i, num_cols ) {

        let col_shift: f64 = col as f64 * tile_size as f64;

        c.square(
            col_shift,
            row_shift,
            tile_size as f64
        ).rgb( red, 0.0, 0.0).draw(gl);                                

    }
}

What does this do? First we are looping through our rows from zero go num_rows (we calculated the number of rows earlier). On each row we adjust our redness slightly this should make each row more red than the last with the first row being fairly dark. Next we calculate row_shift this is simply done my multiplying what row we are on by the size of our tiles. This will be used to tell the context to move down 32 pixels when it gets to row 2, and down 64 pixels when it gets to row 3 and so forth. The inner loop does the same only for our columns. We loop through each column and calculate our col_shift or how far to shift to the right for each column. If I recall correctly this is the most efficient way to loop since the screen paints outwards from your upper-left corner. Finally, we draw our square. The context (c) knows how to draw squares so we pass into it the coordinates of the upper-left corner of our square (col_shift, row_shift), the width of our square as a float (tile_size), instruct the context to fill this square by calling rgb( red, 0.0, 0.0 ). Note, we passed in our red variable so the redness of the tiles should adjust as the red variable does. Last, we draw the square by calling draw and once again passing in gl.

Call cargo build and cargo run and enjoy!


September 26, 2014

Centipede-RS Dev Log #1

Filed under: Journal,Software Development — Tags: , , — Joseph @ 7:23 pm

Flattr this!

A rather rambling design document for my ideas for a Centipede clone that I’m releasing under the MIT license. Following all my reading in Rust it seems like a good idea to have some kind of project to complete. After scrounging about for ideas, I came up with the one of doing an open source centipede clone using Piston. This would be good practice for trying a Rust Ludum Dare next April.

The following is more or less a rambling stream of consciousness design doc for what I’m about to do. I’ll probably follow this up with a series of other entries about the steps and break down of the code as I go.

Concept

A Centipede clone done in Rust using Piston with perhaps some additional flavor.

The core idea of the game is to have a gridded window of size X and Y with a centipede that begins with one segment that grows as the game progresses. The centipede moves continuously in the last cardinal direction specified by the player. As the character moves it encounters various items randomly populated on the screen. Upon contact some effect occurs such as adding an additional segment. If the user comes into contact with itself (such as looping back around on it’s own tail). The game ends or some failure condition occurs.

Objects in the Game

The Game

Well of course it’s an object unto itself. The game represents the game loop.

The Board

The board is 800×480 and divided into 32 pixel squares. At start of the game and at a fixed interval actors are randomly assigned squares on the board.

Centipede

The centipede has the following characteristics:

  • Collection of Segments
  • Who each have a position and sprite
  • Who each have a direction (Each moves in the direction of the segment before it except the head segment which moves in the last direction input by the player).
  • If a segment intercepts another segment it destroys it. The severed segment then becomes bombs.
  • Number of mushrooms eaten (Used as a score)

Actors

Actors specifies an indescriminate number of items placed on the board that the centipede interacts with when it comes into contact with them. The actors need to be able to expand to include new actors with new effects.

  • Sprite
  • Board position
  • An affect

Right now we have two actors: mushrooms and bombs. Mushrooms are placed randomly on the board at a fixed interval. Bombs are segments that have seperated from the centipede. They each have an affect. Mushrooms cause a new segment to be added to the centipede after X mushrooms have been consumed. Bombs cause the game to immediately end.




« Newer PostsOlder Posts »

Copyright 2011 - 2017 Joseph Hallenbeck Powered by WordPress