Sprites and Things 2(In Jamagic)
Author: | vortex2
|
Submitted: | 21st December, 2003
|
Views: | 5690
| Rated: |
|
|
Introduction:
Hello and welcome to part 2 of the Vortex guide to Sprites and Things in Jamagic.
This tutorial is basically an extention of the previous one so if you have not read it, please get it from: http://www.create-games.com/article.asp?id=1228 .
If you have already read this tutorial covering the basics of sprite creation, animation, and movement please continue reading .
After you played with animations for sprites, and moving them around the screen, you may be wondering how to change the sprites direction or animation as the sprite walks along the screen. Well, the first part of this tutorial will cover two methods for setting the static direction for a sprite. Then it will go into animations that loop infinite when the player walks, and then it will cover making a stopped direction as well by combining both methods together to get a very nice result. After that we will explore a non user driven movement called the Bouncing Ball, that is used alot in the click line of products. So if you feel like you are ready to explore the amazing world of Sprites and things then please continue reading.
Moving in Directions:
Ah moving in directions, this is done so easily in the click line of products but if you have used Jamagic you may be wondering "How can I do it?" well, I am here to show you a way using 8 pictures for each direction of the 8 directional movement, or by using an animation for the static direction.
First off for the following examples you can use the old product started in Sprites and Things, or you can create a new project.
Next, you will need to create 8 images to represent the directions.
To avoid confusion and make it easier to code, i recommend you use a standard naming system for all the directions as this program will do.
The picture names should be as follows: myBall_UP ,myBall_UPRIGHT,myBall_UPLEFT, myBall_DOWN,myBall_DOWNRIGHT,myBall_DOWNLEFT ,myBall_RIGHT, myBall_LEFT
You will see why naming our images this way has benifits as we can easily tell which is which as we write our program. and latter on we will need to use just a directional variable to switch between the walk animations, and the stopped animations.
Once you have 8 pictures named myBall_UP ,myBall_UPRIGHT,myBall_UPLEFT, myBall_DOWN,myBall_DOWNRIGHT,myBall_DOWNLEFT ,myBall_RIGHT, myBall_LEFT
please continue reading. If you do not name these correctly or have all of them in the program, you WILL GET AN ERROR. So please have your pictures!
The following code will adapt the 8 directional movement introduced in Sprites and things 1 to have static directions .
_________________________
//sets auto refresh off for the window
Defaultwin.SetAutoRefresh(OFF);
//Creates a sprite
mySprite=New Sprite(DefaultWin,0,0,"myBall");
//makes a new hero object
myHero=New Hero(mySprite,3);
//loop to keep the program running
While(1)
{
//makes a variable used to limit the fps
ti=System.GetElapsedTime()+30;
//called the move method of the hero object
myHero.Move();
//refreshes the screen manually.
Defaultwin.Refresh();
//limits fps
While(System.GetElapsedTime()<ti);
}
//constructor for the hero object
Function Hero(spr,speed)
{
//makes the spr variable global to this object
This.spr=spr;
//makes the speed variable global to this object
This.speed=speed;
//defines the dir variable used to set the direction of the sprite
This.dir="UP";
//gets the default game input device and makes it global to this object
This.gInput=Program.GetDefaultGameInput();
//function to call when the method move is called for this object
This.Move=Hero_Move;
}
//function for the move method of the hero object It uses the common namming system of ObjectName_MethodName
Function Hero_Move()
{
//defines a variable called v used for x movement later on
v=0;
//defines a variable called w used for y movement later on
w=0;
//sets the topVal variable to get the result if the Top key is pressed
topVal=gInput.GetDeviceValue(0,"Top");
//sets the botVal variable to get the result if the Bottom key is pressed
botVal=gInput.GetDeviceValue(0,"Bottom");
//sets the rightVal variable to get the result if the Right key is pressed
rightVal=gInput.GetDeviceValue(0,"Right");
//sets the leftVal variable to get the result if the left key is pressed
leftVal=gInput.GetDeviceValue(0,"Left");
//if statement for the topVal variable
If(topVal!=0)
{
//subtracts 1 from the w variable. it subtracts instead of sets incase you push top and bottom at once
w-=1;
}
//if statement for the botVal variable
If(botVal!=0)
{
//adds 1 to the w variable. it adds instead of sets incase you push top and bottom at once
w+=1;
}
//if statement for the rightVal variable
If(rightVal!=0)
{
//adds 1 to the v variable
v+=1;
}
//if statemetn for the leftVal variable
If(leftVal!=0)
{
//subtracts 1 to the v variable
v-=1;
}
//If the values of v,w produce an up movement
If(v==0&&w==-1)
{
dir="UP";
}
//if the values of v,w produce a down movement
If(v==0&&w==1)
{
dir="DOWN";
}
//if the values of v,w produce a right movement
If(v==1&&w==0)
{
dir="RIGHT";
}
//if the values of v,w produce a left movement
If(v==-1&&w==0)
{
dir="LEFT";
}
//if the values of v,w produce a lower right movement
If(v==1&&w==1)
{
dir="DOWNRIGHT";
}
//if the values of v,w produce a upper right movement
If(v==1&&w==-1)
{
dir="UPRIGHT";
}
//if the values of v,w produce a lower left movement
If(v==-1&&w==1)
{
dir="DOWNLEFT";
}
//if the values of v,w produce a upper left movement
If(v==-1&&w==-1)
{
dir="UPLEFT";
}
//sets the variable to the postion based off the current x,y and if the v,w variables are positive and negative and sets the picture to a direction pic
spr.Set(mySprite.GetX()+v*speed,mySprite.GetY()+w*speed,"myBall_"+dir);
}
_______________________
This basically codes the diffrent directions by using 8 if statements and a variable. the dir variable could contain : dir="myBall_RIGHT" but i was trying to show how using a naming system can be helpful.
This is all well and good, but there are two other ways to go about doing this.
The next example will use a 2d array to store the pictures this will save some code and probally be easier to understand.
However, I will use this time to discuss solving a programming problem . You see, if we wanted to use an array for the directions for our 8 way movement, we run into a small problem. v,w run from -1 to 1 and arrays cannot have negative values. The solution is simple this time, we simply add 1 to v,w and we get the right result.
This next code will use an array to set the direction of our 8 way movement while still showing how a naming convention can be used.
______________________
//sets auto refresh off for the window
Defaultwin.SetAutoRefresh(OFF);
//Creates a sprite
mySprite=New Sprite(DefaultWin,0,0,"myBall");
//makes a new hero object
myHero=New Hero(mySprite,3);
//loop to keep the program running
While(1)
{
//makes a variable used to limit the fps
ti=System.GetElapsedTime()+30;
//called the move method of the hero object
myHero.Move();
//refreshes the screen manually.
Defaultwin.Refresh();
//limits fps
While(System.GetElapsedTime()<ti);
}
//constructor for the hero object
Function Hero(spr,speed)
{
//makes the spr variable global to this object
This.spr=spr;
//makes the speed variable global to this object
This.speed=speed;
//defines the array variable and makes it global
This.myArray=0;
//sets up the directions in the array
myArray[0,0]="UPLEFT";
myArray[0,1]="LEFT";
myArray[0,2]="DOWNLEFT";
myArray[1,0]="UP";
myArray[1,2]="DOWN";
myArray[2,0]="UPRIGHT";
myArray[2,1]="RIGHT";
myArray[2,2]="DOWNRIGHT";
//gets the default game input device and makes it global to this object
This.gInput=Program.GetDefaultGameInput();
//function to call when the method move is called for this object
This.Move=Hero_Move;
}
//function for the move method of the hero object It uses the common namming system of ObjectName_MethodName
Function Hero_Move()
{
//defines a variable called v used for x movement later on
v=0;
//defines a variable called w used for y movement later on
w=0;
//sets the topVal variable to get the result if the Top key is pressed
topVal=gInput.GetDeviceValue(0,"Top");
//sets the botVal variable to get the result if the Bottom key is pressed
botVal=gInput.GetDeviceValue(0,"Bottom");
//sets the rightVal variable to get the result if the Right key is pressed
rightVal=gInput.GetDeviceValue(0,"Right");
//sets the leftVal variable to get the result if the left key is pressed
leftVal=gInput.GetDeviceValue(0,"Left");
//if statement for the topVal variable
If(topVal!=0)
{
//subtracts 1 from the w variable. it subtracts instead of sets incase you push top and bottom at once
w-=1;
}
//if statement for the botVal variable
If(botVal!=0)
{
//adds 1 to the w variable. it adds instead of sets incase you push top and bottom at once
w+=1;
}
//if statement for the rightVal variable
If(rightVal!=0)
{
//adds 1 to the v variable
v+=1;
}
//if statemetn for the leftVal variable
If(leftVal!=0)
{
//subtracts 1 to the v variable
v-=1;
}
//we dont want the direction to change if the ball isnt moving .
If(v!=0||w!=0)
{
//sets the variable to the postion based off the current x,y and if the v,w variables are positive and negative and sets the picture to a direction pic
spr.Set(mySprite.GetX()+v*speed,mySprite.GetY()+w*speed,"myBall_"+myArray[v+1,w+1]);
}
}
___________________
Run the program and you will see how usefull arrays can be! Hey that rymes . Anyway, this saves a good amount of code, and I think it makes things less confusing and easier to change .
Now, this method works well, saves space and there is really no point to use a diffrent method. However, for the sake of showing you how, i will show you how to change the directions through a stopped animation.
For this next example you will need to create an animation called myBall_STOP
This will basically be 8 frames, and contain the pictures you created previously.
Here is the order the pictures should go as the example will use them:
Frame 0=UP
Frame 1=UPRIGHT
Frame 2=RIGHT
Frame 3=DOWNRIGHT
Frame 4=DOWN
Frame 5=DOWNLEFT
Frame 6=LEFT
Frame 7=UPLEFT
Once you finish the 32X32 8 frame animation in that format, please continue.
This next example will show how to change the direction of the sprite through an Animation.
______________
//sets auto refresh off for the window
Defaultwin.SetAutoRefresh(OFF);
//Creates a sprite
mySprite=New Sprite(DefaultWin,0,0,"myBall");
//makes a new hero object
myHero=New Hero(mySprite,3);
//loop to keep the program running
While(1)
{
//makes a variable used to limit the fps
ti=System.GetElapsedTime()+30;
//called the move method of the hero object
myHero.Move();
//refreshes the screen manually.
Defaultwin.Refresh();
//limits fps
While(System.GetElapsedTime()<ti);
}
//constructor for the hero object
Function Hero(spr,speed)
{
//makes the spr variable global to this object
This.spr=spr;
//makes the speed variable global to this object
This.speed=speed;
//defines the array variable and makes it global
This.myArray=0;
//sets up the directions in the array
myArray[0,0]=7;
myArray[0,1]=6;
myArray[0,2]=5;
myArray[1,0]=0;
myArray[1,2]=4;
myArray[2,0]=1;
myArray[2,1]=2;
myArray[2,2]=3;
//gets the default game input device and makes it global to this object
This.gInput=Program.GetDefaultGameInput();
//function to call when the method move is called for this object
This.Move=Hero_Move;
}
//function for the move method of the hero object It uses the common namming system of ObjectName_MethodName
Function Hero_Move()
{
//defines a variable called v used for x movement later on
v=0;
//defines a variable called w used for y movement later on
w=0;
//sets the topVal variable to get the result if the Top key is pressed
topVal=gInput.GetDeviceValue(0,"Top");
//sets the botVal variable to get the result if the Bottom key is pressed
botVal=gInput.GetDeviceValue(0,"Bottom");
//sets the rightVal variable to get the result if the Right key is pressed
rightVal=gInput.GetDeviceValue(0,"Right");
//sets the leftVal variable to get the result if the left key is pressed
leftVal=gInput.GetDeviceValue(0,"Left");
//if statement for the topVal variable
If(topVal!=0)
{
//subtracts 1 from the w variable. it subtracts instead of sets incase you push top and bottom at once
w-=1;
}
//if statement for the botVal variable
If(botVal!=0)
{
//adds 1 to the w variable. it adds instead of sets incase you push top and bottom at once
w+=1;
}
//if statement for the rightVal variable
If(rightVal!=0)
{
//adds 1 to the v variable
v+=1;
}
//if statemetn for the leftVal variable
If(leftVal!=0)
{
//subtracts 1 to the v variable
v-=1;
}
//we dont want the direction to change if the ball isnt moving .
If(v!=0||w!=0)
{
//sets the variable to the postion based off the current x,y and if the v,w variables are positive and negative and sets the animation to the stopped anm
spr.Set(mySprite.GetX()+v*speed,mySprite.GetY()+w*speed,"myBall_STOP");
//sets the frame to the value in myArray
spr.SetFrame(myArray[v+1,w+1]);
}
}
___________
Run it, and if you did everything correctly it will set the current direction of the sprite through an ANIMATION if this is more organized then the previous example or not is up to you but I think it is cool that you don't have to have 8 seperate images but one animation .
Next thing we will learn is how to have walking animations while you move.
For this example you will need to do some additional graphics work. You will need to create an animation for every direction you want. In our case that is 8 directions.
When creating your animations use a standard naming convention like we learned earlier to help make our animations easier to tell apart and understand.
In my example the animations will be named as follows: myBall_WALK_UP,myBall_WALK_UPRIGHT,myBall_WALK_RIGHT,myBall_WALK_DOWNRIGHT,myBall_WALK_DOWN,myBall_WALK_DOWNLEFT,myBall_WALK_LEFT,myBall_WALK_UPLEFT.
for the purpose of this example I am just using the same frames as in our myBall_STOP animation but changing their colors. so when our ball walks, it will change colors. My ball goes from red, green, blue, and yellow (as you will recall our first exploration into animations did).
Once you have finished all 8 animations, please continue.
This next example will show how to do animations when you walk, and stopped when you dont.
______________________
//sets auto refresh off for the window
Defaultwin.SetAutoRefresh(OFF);
//Creates a sprite
mySprite=New Sprite(DefaultWin,0,0,"myBall");
//makes a new hero object
myHero=New Hero(mySprite,3);
//loop to keep the program running
While(1)
{
//makes a variable used to limit the fps
ti=System.GetElapsedTime()+30;
//called the move method of the hero object
myHero.Move();
//refreshes the screen manually.
Defaultwin.Refresh();
//limits fps
While(System.GetElapsedTime()<ti);
}
//constructor for the hero object
Function Hero(spr,speed)
{
//makes the spr variable global to this object
This.spr=spr;
//makes the speed variable global to this object
This.speed=speed;
//defines the array variable and makes it global
This.myArray=0;
//sets up the directions in the array
myArray[0,0]="UPLEFT";
myArray[0,1]="LEFT";
myArray[0,2]="DOWNLEFT";
myArray[1,0]="UP";
myArray[1,2]="DOWN";
myArray[2,0]="UPRIGHT";
myArray[2,1]="RIGHT";
myArray[2,2]="DOWNRIGHT";
//gets the default game input device and makes it global to this object
This.gInput=Program.GetDefaultGameInput();
//function to call when the method move is called for this object
This.Move=Hero_Move;
}
//function for the move method of the hero object It uses the common namming system of ObjectName_MethodName
Function Hero_Move()
{
//defines a variable called v used for x movement later on
v=0;
//defines a variable called w used for y movement later on
w=0;
//sets the topVal variable to get the result if the Top key is pressed
topVal=gInput.GetDeviceValue(0,"Top");
//sets the botVal variable to get the result if the Bottom key is pressed
botVal=gInput.GetDeviceValue(0,"Bottom");
//sets the rightVal variable to get the result if the Right key is pressed
rightVal=gInput.GetDeviceValue(0,"Right");
//sets the leftVal variable to get the result if the left key is pressed
leftVal=gInput.GetDeviceValue(0,"Left");
//if statement for the topVal variable
If(topVal!=0)
{
//subtracts 1 from the w variable. it subtracts instead of sets incase you push top and bottom at once
w-=1;
}
//if statement for the botVal variable
If(botVal!=0)
{
//adds 1 to the w variable. it adds instead of sets incase you push top and bottom at once
w+=1;
}
//if statement for the rightVal variable
If(rightVal!=0)
{
//adds 1 to the v variable
v+=1;
}
//if statemetn for the leftVal variable
If(leftVal!=0)
{
//subtracts 1 to the v variable
v-=1;
}
//we dont want the direction to change if the ball isnt moving .
If(v!=0||w!=0)
{
//sets the variable to the postion based off the current x,y and if the v,w variables are positive and negative
spr.Set(mySprite.GetX()+v*speed,mySprite.GetY()+w*speed);
//used so you dont always reset the animation
If(Spr.IsPlaying()==FALSE)
{
//sets the animation to the proper animation based on the value in the array
spr.Set(,,"myBall_WALK_"+myArray[v+1,w+1]);
//plays the animation once
spr.Play();
}
}
}
____________
Run the example and you will see the ball play your animation in the direction you move so cool! oh and by testing this it appears the stopped picture will be the last picture in the animation not the first.
And thus this section comes to a close, but there will be more so read on .
Some Mouse movement just for you:
In the following two examples for quick refrence i will post some simple code to A) Set the ball sprite to the x,y mouse pos, and B) Set the ball sprite to a grid based mouse movement.
The following example will show how to set the ball sprite the the mouse.
_____________
//sets auto refresh off
Defaultwin.SetAutoRefresh(OFF);
//makes a new sprite
myBall=New Sprite(Defaultwin,0,0,"myBall");
//loop to keep the program running
While(1)
{
//used later to limit the fps to 30 fps
ti=System.GetElapsedTime()+30;
//sets the myBall sprite to the x,y mouse positions -16 which centers the ball on the mouse
myBall.Set(Defaultwin.GetXMouse()-16,Defaultwin.GetYMouse()-16);
//refreshes the screen
Defaultwin.Refresh();
//used to limit the fps
While(System.GetElapsedTime()<ti);
}
_______________
Run the code, and you will see it set the sprite to the x,y mouse positions very neat .
This next example will show how to change this code to make it grid based .
__________
//sets auto refresh off
Defaultwin.SetAutoRefresh(OFF);
//makes a new sprite
myBall=New Sprite(Defaultwin,0,0,"myBall");
//loop to keep the program running
While(1)
{
//used later to limit the fps to 30 fps
ti=System.GetElapsedTime()+30;
//sets the myBall sprite to the x,y mouse positions /32*32 which makes it grid based
myBall.Set(((Defaultwin.GetXMouse())/myBall.GetWidth())*myBall.GetWidth(),((Defaultwin.GetYMouse())/myBall.GetHeight())*myBall.GetHeight());
//refreshes the screen
Defaultwin.Refresh();
//used to limit the fps
While(System.GetElapsedTime()<ti);
}
_____________
Run the code and you will notice how the ball always stays in an invisable grid. But who wants an invisable grid?
In the next example I have written a small function to draw a grid on the screen
______________
//sets auto refresh off
Defaultwin.SetAutoRefresh(OFF);
//makes a new sprite
myBall=New Sprite(Defaultwin,0,0,"myBall");
//function called to draw a visable grid to the screen
DrawGrid(Defaultwin,myBall,BLACK);
//loop to keep the program running
While(1)
{
//used later to limit the fps to 30 fps
ti=System.GetElapsedTime()+30;
//sets the myBall sprite to the x,y mouse positions /32*32 which makes it grid based
myBall.Set(((Defaultwin.GetXMouse())/myBall.GetWidth())*myBall.GetWidth(),((Defaultwin.GetYMouse())/myBall.GetHeight())*myBall.GetHeight());
//refreshes the screen
Defaultwin.Refresh();
//used to limit the fps
While(System.GetElapsedTime()<ti);
}
Function DrawGrid(win,spr,pencol)
{
//sets the pen color for the window
win.SetPenColor(pencol);
//starts a for loop for the width of the window divided by the width of the sprite
For(a=0;a<=win.GetWidth()/spr.GetWidth();a++)
{
//starts a for loop for the height of the window divided by the height of the sprite
For(b=0;b<=win.GetHeight/spr.GetHeight();b++)
{
//draws a rectangle to the screen at the value of a*the width of the sprite, b*the width of the sprite that is the width,height of the sprite big
win.Rectangle(a*spr.GetWidth(),b*spr.GetHeight(),spr.GetWidth(),spr.GetHeight());
}
}
}
_______________
There, run that code and now we can SEE it stay in the grid . Cool huh?
After we see some diffrent types of user input controlled movement, lets explore a commonly used form of non user controlled movement. the Bouncing Ball.
Non user controlled movements:
Here is an example of making a ball bounce around the screen. To use this example all you will need is the orginal ball image we made .
_________
//sets auto refresh off for the window
Defaultwin.SetAutoRefresh(OFF);
//makes a new sprite
mySpr=New Sprite(Defaultwin,0,0,"myBall");
//makes a new ball object from the sprite with a speed of 3
myBall=New Ball(Defaultwin,mySpr,3);
//while loop to execute statements and keep app running
While(1)
{
//used later to limit the fps
ti=System.GetElapsedTime()+30;
//method called to move the ball
myBall.Move();
//refreshes the window
Defaultwin.Refresh();
//used to limit the fps
While(System.GetElapsedTime()<ti);
}
//constructor for a ball object containing a window parameter, sprite parameter, and speed parameter
Function Ball(win,spr,speed)
{
//makes the function parameters global
This.win=win;
This.spr=spr;
This.speed=speed;
//defines our movement vectors (notice how these are 1 not 0)
This.v=1;
This.w=1;
//sets the direction to a random direction or 0-44
This.dir=Random(45);
//function to call when the Move method of this object is called
This.Move=Ball_Move;
}
//function called when the move method of the ball object is called
Function Ball_Move()
{
//moves the sprite using trig. cose,sine need to convert angles to radians. the *speed converts from polar to cartesian cordinates
spr.Set(spr.GetX()+v*Cos(GetRadian(dir))*speed,spr.GetY()+w*Sin(GetRadian(dir))*speed);
//used to test if the sprite is leaving the left or right of the window
If(spr.GetX()<0||spr.GetX()+spr.GetWidth()>win.GetWidth())
{
//if so it reverses our movement vector
v*=-1;
//and gives it a random direction
dir=Random(45);
}
//used to test if the sprite is leaving the top or the bottom of the window
If(spr.GetY()<0||spr.GetY()+spr.GetHeight()>win.GetHeight())
{
//if so it reverses our movement vector
w*=-1;
//and gives it a random direction
dir=Random(45);
}
}
_______________
Run this code, and you will see a ball bouncing around the screen . The new things we learn here are A) A form of collisions using if statements, and B) How to use trig to convert angles to positions.
the if statements say if the ball is lower then 0 OR if the ball position + the size of the ball is greater then the size of the window, then reverse the direction.
You will notice how this has a lot of diffrent directions and is random .
Now that you have learnt how to do animations, directions, diffrent types of user controlled movements, and non user controlled movements, I will end this tutorial to let it all sink in.
Next time on Sprites and things , we will explore how to handle multiple sprites on the screen, diffrent types of collisions, and more .
I hope you have enjoyed reading this tutorial. Thank you for your time and good luck in your Jamagic learning adventures.
Questions/Comments ? Please reply or email me at n2cartoons@hotmail.com
|
|
vortex2
Registered 27/05/2002
Points 1406
|