The entire source code for the game can be downloaded from here.
The source code has three files, tank.fx, monster.fx and Main.fx. In this post we will talk about tank.fx. This class controls the movements, shooting and everything else to do with the tank. Here it is:
/*
* tank.fx
*
* Created on Jun 21, 2009, 9:19:12 AM
*/
package spaceinvadersfx;
import javafx.scene.image.ImageView;
import javafx.scene.image.Image;
import javafx.scene.CustomNode;
import javafx.scene.Node;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Polygon;
import javafx.scene.paint.Color;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.Interpolator;
/**
* @author Sagar Jauhari
*/
public class tank extends CustomNode {
var monster = monsters{};
var fireAgain = true;
var tankX: Integer;
var tankY = 400;
var bulletX: Integer;
var bulletY = 400;
var visiblity = false;
var image = ImageView {
x: bind tankX, y: tankY
image: Image {
url: "{__DIR__}resources/tank 50X50.png"
}
};
var bg = ImageView {
onKeyPressed: function( e: KeyEvent ) {
if(e.code == KeyCode.VK_LEFT){
if(tankX >= 50){
tankX-=50;
}
}
if(e.code == KeyCode.VK_RIGHT){
if(tankX <= Main.screenWidth - 100){
tankX+=50;
}
}
}
onMouseClicked: function( e: MouseEvent ):Void {
fire();
}
image: Image {
url: "{__DIR__}resources/bg.jpg"
}
};
var bullet = Polygon {
visible: bind visiblity
translateX: bind bulletX
translateY: bind bulletY
points : [ 0,7, 5,0, 10,7, 10,15, 5,5, 0,15 ]
fill: Color.YELLOW
stroke: Color.RED
}
var timeline = Timeline {
repeatCount: 1
keyFrames : [
at (0s) {bulletX => tankX+20; bulletY => tankY; visiblity => true; fireAgain=> false },
at (1s) {bulletY=> -20; visiblity => true; fireAgain=> true}
]
}
var colissionTimeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : 0.1s
action: function(){colissionDetect()}
}
]
}
public function fire(){
if(fireAgain){
timeline.playFromStart();
}
}
public function colissionDetect(){
if(monster.intersects(bulletX,bulletY,10,15)){
monster.isDead();
}
}
public override function create() :Node{
bg.requestFocus();
colissionTimeline.play();
return{
Group{
content: bind[bg,image,bullet,monster]
}
}
}
}
Understanding the code:
- First of all, we make an image of tank of 50X50px. Here's the image I made in GIMP:
- Next, we import it for using:
var image = ImageView {
x: bind tankX, y: tankY
image: Image {
url: "{__DIR__}resources/tank 50X50.png"
}
}; - Now we put a background image and add all the mouse and keyboard triggers to it.
var bg = ImageView {
onKeyPressed: function( e: KeyEvent ) {
if(e.code == KeyCode.VK_LEFT){
if(tankX >= 50){
tankX-=50;
}
}
if(e.code == KeyCode.VK_RIGHT){
if(tankX <= Main.screenWidth - 100){
tankX+=50;
}
}
}
onMouseClicked: function( e: MouseEvent ):Void {
fire();
}
image: Image {
url: "{__DIR__}resources/bg.jpg"
}
}; - Now we come to the more interesting part: the shooting! :). To represent a bullet, I made a polygon. The idea is to traverse this polygon from bottom to top by binding its y coordinate to a variable and linearly varying that variable with time using the Timeline class. Initially the bullet is invisible, then, while shooting it becomes visible and then again it becomes invisible. This gives the impression that multiple bullets are being shot contrary to the fact that actually, it is the same bullet again and again! Also, there is a constraint that at any point of time, only one bullet is in the scene. This is managed by the 'fireAgain' flag. See here:
var bullet = Polygon {
visible: bind visiblity
translateX: bind bulletX
translateY: bind bulletY
points : [ 0,7, 5,0, 10,7, 10,15, 5,5, 0,15 ]
fill: Color.YELLOW
stroke: Color.RED
}
var timeline = Timeline {
repeatCount: 1
keyFrames : [
at (0s) {bulletX => tankX+20; bulletY => tankY; visiblity => true; fireAgain=> false },
at (1s) {bulletY=> -20; visiblity => true; fireAgain=> true}
]
} - Finally, there's this function called fire() which fires the bullet.
public function fire(){
if(fireAgain){
timeline.playFromStart();
}
}
great work, like the part where you explain the code..
ReplyDeleteway to go! cheers.. :)
hey dude, u may not know me, but i am bitsgian too, 2009 passout and have great interest in java,linux just like u, great work dude... got a good source of inspiration from u :).
ReplyDeleteKeep going...
Vidyuth
thanks Mohit, thanks Viduth for the compliments. You all motivate me ! :)
ReplyDelete