Making a ball bounce with Simple Game Framework
While doing research for my book, I've had the opportunity to play around with dozens of game engine frameworks in search of ones with a fluent yet concise API. One framework that I devote part of a chapter to is Simple Game Framework. The Simple Game Framework, or SGF for short doesn't use the Canvas and instead uses HTML divs and css. I think it is a great stepping stone to advanced technologies like the Canvas and WebGL. SGF uses Prototype to make its code object-oriented. It's not as nice as CoffeeScript but definitely a nicer experience than using the JavaScript prototype directly. In this snippet, we can see the code in the main.js file. Every SGF application must have a main.js file that kicks off the application. Just think of it as a SGF version of the public static main function in Java. After importing some classes from the SGF namespace, we dynamically load our Ball class and draw an instance upon load.
// Import required classes
var Game = SGF.require("Game");
var Rectangle = SGF.require("Rectangle");
// Get a reference to our Game instance
var myGame = Game.getInstance();
var game_height = 400;
var game_width = 400;
myGame.getScript("Ball.js", function(){
myGame.ball = new Ball();
myGame.addComponent(myGame.ball);
});
Next, we need to create our ball class. Ball inherits from Rectangle and in the contructor, we set some attributes on it. The Direction object is an abstraction over a directional vector. Moving one unit down and one unit to the right and flipping the direction if it hits something is much more simple than trying to calculate the angles of reflection/inflection. Multipliers were applied to the direction vector to make the movement more dynamic and less linear.
var Ball = Class.create(Rectangle, {
initialize: function(SimpleTemplateScript296@1ad55833){
SimpleTemplateScript296@1ad55833();
this.width = 20;
this.height = 20;
this.color = "FF0000";
this.setPosition(200, 130);
this.direction = new Direction();
this.direction.pickDirection();
},
checkCollisions: function(){
// Collisions with walls
if (this.x <= 0 || this.x >= game_width - 20)
this.direction.flipEastWest();
if (this.y <= 0 || this.y >= game_height - 20)
this.direction.flipNorthSouth()
},
update: function(){
this.checkCollisions();
pos = this.getPosition()
this.setPosition(pos.x - 2 * this.direction.getX(), pos.y - 3 * this.direction.getY())
}
});
Behind the scenes, the framework is handling the game loop for you. The contents of the update function on a game object is auto-magically executed every time there is a frame refresh. Lastly, we need a bit of HTML to tie it all together. The interesting bit here is the script tag which dynamically loads the assets for the demo. data-screen tells it to draw itself in a specific div. Omitting that property will give the application the full body area. Because the assets are loaded dynamically, it is good practice to set the sizes for your app in CSS.
<!DOCTYPE HTML>
<html>
<head>
<title>BouncingBall</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- For IE. Force the browser to the most current rendering mode. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" >
<!-- A few basic styles. These are NOT mandatory for SGF... -->
<link href="styles.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="js/SGF.js"
data-debug="true"
data-prototype="lib/prototype.js"
data-swfobject="lib/swfobject.js"
data-screen="screen"
data-game="BouncingBall"></script>
</head>
<body>
<div id="screen"></div>
</body>
</html>
Is SGF suited for a first person shooter, probably not, but it is perfectly serviceable. Check out examples like this and more in my book: Learning HTML5 Game Programming.