Test driven game development silly, stupid or inspired?
-
Upload
eric-smith -
Category
Technology
-
view
1.101 -
download
1
Transcript of Test driven game development silly, stupid or inspired?
Tuesday, August 13, 13
Tuesday, August 13, 13
//// build composite position//! movl! ebp,[_ds_xfrac]! shll! ebp,10! andl! ebp,0ffff0000h! movl! eax,[_ds_yfrac]! shrl! eax,6! andl! eax,0ffffh! orl!ebp,eax
! movl! esi,[_ds_source]
//// calculate screen dest//! movl! edi,[_ds_y]! movl! edi,[_ylookup+edi*4]! movl! eax,[_ds_x1]! addl edi,[_columnofs+eax*4]
//// build composite step//! movl! ebx,[_ds_xstep]! shll! ebx,10! andl! ebx,0ffff0000h! movl! eax,[_ds_ystep]! shrl! eax,6! andl! eax,0ffffh! orl!ebx,eax
! movl! ! eax,OFFSET hpatch1+2! ! // convice tasm to modify code...! movl! ! [eax],ebx! movl! ! eax,OFFSET hpatch2+2! ! // convice tasm to modify code...! movl! ! [eax],ebx
// eax!! aligned colormap// ebx!! aligned colormap// ecx,edx! scratch// esi!! virtual source// edi!! moving destination pointer// ebp!! frac
! shldl ecx,ebp,22!
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
TDD and GamesSilly, Stupid or Inspired?
Tuesday, August 13, 13
var spaceImage = $("<img src='images/space_background.png'>");
spaceImage.load(function() { spaceBackground = spaceImage.get(0);});
var playerImage = $("<img src='images/player.png'>");playerImage.load(function() { player = playerImage.get(0);});
var bulletJQueryImage = $("<img src='images/bullet.png'>");bulletJQueryImage.load(function() { bulletImage = bulletJQueryImage.get(0);});
Tuesday, August 13, 13
var context, spaceBackground, player, bulletImage, spiderImage, bullets = [], spiders = [], startTicks, lastGeneration, laserBeam, gameOn = true, explosion, pop, backgroundMusicTuesday, August 13, 13
Tuesday, August 13, 13
Scheduler ◦ schedules method called for repeated calls: ✓ schedules method called for repeated calls ◦ clears the interval when stop is called: ✓ clears the interval when stop is called ◦ calls that method with the tick rate: ✓ calls that method with the tick rate (200ms) ◦ returns the time for tics: ✓ returns the time for tics ◦ returns its tick time: ✓ returns its tick time
99 tests complete (743 ms)Done. Build script exited with 0
Tuesday, August 13, 13
Eskimo!
Tuesday, August 13, 13
Tuesday, August 13, 13
?Tuesday, August 13, 13
it("uses an associated loader to create a level object, if one exists", function() { var gameDescription = { "newLevel": { "gameObject" : { "customObject" : {} } } };
var customObjectLoader = { load: function(levelSpec, objectName, level, callback) { callback(objectName, {levelSpec: levelSpec, objectName: objectName, level: level}); } }; var gameSpec = new GameSpec({ assetDefinition: gameDescription }); gameSpec.registerLoader('customObject', customObjectLoader);
gameSpec.load("newLevel", function(level) { var loadedObject = level.gameObject('gameObject'); assert.strictEqual(loadedObject.level, level); }); });
Tuesday, August 13, 13
var Eskimo = require('../src/main'), canvas, should = require('should'), assert = require('assert'), emptyFunction = function() {}, emptyDocument = {documentElement: null}, jquery = require("jquery"), FixedGameLoop = require("../src/fixed-game-loop"), ObjectPipeline = require('../src/object_pipeline/display_visible_objects.js'), sandbox = require('sinon').sandbox.create(), levels = {};
function dependencies(customConfig) { var dependencyConfig = { game: {create: sandbox.stub().returns({})}, };
if (customConfig !== null) { jquery.extend(dependencyConfig, customConfig); }
return dependencyConfig; }
function configuration(config) { var standardConfig = { canvas: canvas, document: emptyDocument, levels: levels };
if (config !== null) { jquery.extend(standardConfig, config); }
return standardConfig; }
Tuesday, August 13, 13
Tuesday, August 13, 13
KEEPIT
SIMPLESTUPID
Tuesday, August 13, 13
Tuesday, August 13, 13
Hunting
Tuesday, August 13, 13
Console DLL Game Logic
Tuesday, August 13, 13
[Test] public void ItMovesAnArrowInTheCommandedDirection() { var presenter = Substitute.For<Presenter>(); var map = new Map(); var game = new Game(presenter, map); game.SetPlayerQuiver(1);
map.PlaceItem(0, MapItems.Player); map.AddPath(0, 1, Command.Directions.East);
game.Command(new Command { Direction = Command.Directions.East, Order = Command.Commands.Shoot});
Assert.AreEqual(MapItems.Arrow, map.ItemsInCavern(1)[0]); }
Tuesday, August 13, 13
protected void Rest() { DisplayAvailableDirections(); DisplayArrowStatus(); }
Tuesday, August 13, 13
Feeling Good
Tuesday, August 13, 13
Cubicle Wars
Tuesday, August 13, 13
UnityMakes your life easier when it’s not making it harder
Tuesday, August 13, 13
Scripts
Tuesday, August 13, 13
public class NewScript : MonoBehaviour {
// Use this for initialization void Start () { } // Update is called once per frame void Update () { }}
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
void Awake() { stateMachine = new CubicleWarsStateMachine( new HumanPlayer("Player1"), new HumanPlayer("Player2"));
Tuesday, August 13, 13
! ! [Test]! ! public void ItAllowsAddingAUnitToAPlayer()! ! {! ! ! var unit = Substitute.For<Unit>();
! ! ! stateMachine.AddUnitToPlayer("PlayerOne", unit);! ! ! stateMachine.AddUnitToPlayer("PlayerTwo", unit);
! ! ! playerOne.Received().AddUnit(unit);! ! ! playerTwo.Received().AddUnit(unit);! ! }
Tuesday, August 13, 13
Updating the View
Tuesday, August 13, 13
Update the View
public void Attack(Unit unit)! ! {! ! ! if (CurrentState == State.Attacking)! ! ! {! ! ! ! unit.AttackWith(CurrentPlayer.Weapon());
Tuesday, August 13, 13
Shared Interfaces
Tuesday, August 13, 13
C# Eventspublic delegate void GameOverEvent(String winner);
...
public event GameOverEvent GameOver = delegate { };
...
private void AnnouncePlayerWins(){
GameOver(CurrentPlayer.Name);}
Tuesday, August 13, 13
Wiring the Eventsmachine.GameOver += delegate(string winner) {winMessage.SendMessage("ShowWinner", String.Format("{0} wins!", winner));
};
Tuesday, August 13, 13
Health
Tuesday, August 13, 13
“MVC”
Tuesday, August 13, 13
void Update() { // Each update checks if we are waiting, and if so // modulates the color based on the sin wave and the // current time. if (StartWaiting) { renderer.material.color =
tint * wave.at(Time.time); }}
Tuesday, August 13, 13
Effectspublic class SineWave
{! protected float Amplitude { get; set; }! protected float Frequency { get; set; }! protected float Offset { get; set; }
! public SineWave(float amplitude, float frequency, float offset)! {! ! Amplitude = amplitude;! ! Frequency = frequency;! ! Offset = offset;! }
! public float at(float time)! {! ! return (Amplitude * (float)Math.Sin(Frequency * time)) + Offset;! }}
Tuesday, August 13, 13
Effects[Test]public void ItReturnsANormalSinWaveOnTime(){! var sineWave = new SineWave(1, 1, 0);
! Assert.AreEqual(0, sineWave.at(0));! Assert.AreEqual(1, sineWave.at((float) Math.PI / 2.0f));}
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Hypothesis
Tuesday, August 13, 13
Hypothesis
Tuesday, August 13, 13
Tuesday, August 13, 13
-(void) notifyOfSuccessfulDay{ [self.presenter gameOver:Successful];}
-(void) notifyOfFailedDay{ [self.presenter gameOver:Failed];}
-(void) notifyOfKidDeath{ [self.presenter kidsKilledYou];}
-(void) notifyOfWorkDeath{ [self.presenter workKilledYou];}
Tuesday, August 13, 13
It(@"Will inform the employee of clock ticks when the turn ends", ^{ id daddy = [OCMockObject niceMockForProtocol:@protocol(Freelancer)];
WorkdayStateMachine *machine = [WorkdayStateMachine machineWithFreeLancer:daddy presenter:nil]; [machine start];
[[daddy expect] clockTicked];
[machine endTurn];
[daddy verify]; });
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
It(@"is fun", ^{ [ExpectBool(game.fun) toBeTrue];})
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
FTT
• Forget
• The
• Tests
Tuesday, August 13, 13
Sprite *sprite = Sprite::createWithTexture(batchNode->getTexture()); sprite->setPosition(ccp(0, 60)); batchNode->addChild(sprite, 0, kTopBucket); sprite = Sprite::createWithTexture(batchNode->getTexture()); sprite->setPosition(ccp(0, 0)); batchNode->addChild(sprite, 0, kMiddleBucket); sprite = Sprite::createWithTexture(batchNode->getTexture()); sprite->setPosition(ccp(0, -60)); batchNode->addChild(sprite, 0, kBottomBucket);
Tuesday, August 13, 13
Tuesday, August 13, 13
Design Phase
Tuesday, August 13, 13
Bugs
Tuesday, August 13, 13
Tuesday, August 13, 13
Not the Hard Part
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Tuesday, August 13, 13
Throw It Out!
Tuesday, August 13, 13
It(@"lets the lesson know about an incorrect guess if this is the wrong card", ^{ [[lesson expect] incorrectGuess]; [card tap]; [lesson verify]; });
-(void) tap{ self.current ? [self.lesson correctGuess] : [self.lesson incorrectGuess];}
Tuesday, August 13, 13
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{ CGSize textureSize = [self.texture contentSizeInPixels]; if ([Card contains: [self convertTouchToNodeSpaceAR:touch]
inTextureSize:textureSize]) { [self setScale:1.2f]; return true; } return false;}
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{ [self setScale:1.0f]; [self.card tap];}
Tuesday, August 13, 13
<p> <strong>Title:</strong> <%= @post.title %></p> <p> <strong>Text:</strong> <%= @post.text %></p>
Tuesday, August 13, 13
<%= form_for :post, url: posts_path do |f| %> <% if @post.errors.any? %> <div id="errorExplanation"> <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% @post.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end
Tuesday, August 13, 13
Expect(game) toBeFun
Tuesday, August 13, 13
@paytonruleswww.paytonrules.comwww.8thlight.comwww.github.com/paytonrules
Tuesday, August 13, 13
Platinum Sponsors
Gold Sponsors
Tuesday, August 13, 13
August 11th – 13th 2014Same Place, Same Time
Tuesday, August 13, 13