Custom Functions for GE: Easy-to-Use Resuable Code

Compilation of game resources.

Custom Functions for GE: Easy-to-Use Resuable Code

Postby bamby1983 » Sat Mar 23, 2013 1:19 am

The purpose of this thread is to provide the Game Editor community with easy-to-use reusable functions to speed up game development. Most of these functions would need no customization and can simply be used "out-of-the-box" once the code for them has been copy-pasted into the global code.

I will keep updating new functions and their corresponding code on this thread. Each will likely be a separate response to this thread, so I'll try and maintain an index in this original post linking to each of the functions I share.


Links to Posts Regarding Reusable Functions and their Code:

Mouse Look: Look around the game world using just your mouse (as is done in first person shooter games)
Last edited by bamby1983 on Sat Mar 23, 2013 1:44 am, edited 3 times in total.
bamby1983
 
Posts: 112
Joined: Tue Jul 31, 2012 11:36 pm
Score: 8 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby bamby1983 » Sat Mar 23, 2013 1:30 am

CUSTOM FUNCTION: Requires no editing or customization

Mouse Look: Look around the game world using just your mouse (as is done in first person shooter games). This works for 2D as well as simulated 3D GE games.


Features:
1) Look around the screen (auto scroll) horizontally and vertically using just the mouse cursor
2) Locks the crosshairs at the center of the screen (the crosshairs are an actor - the mouse cursor is to be hidden as explained below)
3) The scroll speed is controlled by the speed with which the mouse is moved
4) Allows the user to continue scrolling even after the mouse cursor hits the edge of the screen. However, at this point, the scroll speed will be equal to the mouse scroll speed immediately before the cursor hit the edge of the screen.
5) Prevents the view actor from moving outside the background image area while scrolling in 2D games. This is managed dynamically by the program and automatically adjusts according to the image and view size
6) In simulated 3D games, when the view reaches the edge of the screen, it continues moving from the opposite side of the screen to provide an illusion of a seamless, 3D environment. This requires the background image to have contain the exact same view at the far left and right of the image. The same holds true for the top and bottom. This is done dynamically as well, although it is currently limited to a resolution of 1360 X 768
7) Although not included in the game code posted in this thread, the attached demo contains a feature that actively displays the X and Y mouse scroll speed in real time.


Requirements:
To enable mouse look, you will need:
1) An actor for the crosshairs
2) An actor for the background
3) To copy the function code into the Global Code and save it
4) To hide the mouse cursor (recommended), go to Config -> Game Properties, then click the drop down menu in the screenshot below and select "Hide Mouse"
Image
5) If this is going to be used for a simulated 3D game, the background image will need to be set up so that the edges of the screen corresponding to the view size are identical. Additional efforts may be needed to make actors at the edge of the screen seem consistent (this does not include the Background, view and Crosshair actors).


Using this Function:
To use mouse look, simply paste the following function in your "view" actor's "Draw" event and replace the function parameters to match your game actors. These are explained immediately below the code.

Code: Select all
mouseLook("Background", "Crosshairs", "3D");


"Background" - This is the name of the actor that displays the background image of your game
"Crosshairs" - This is the name of the actor that displays the crosshairs at the center of the screen
"3D" - This denotes whether the game is a 2D game or a simulated 3D game. Enter "2D" for a 2D game and "3D" for a 3D game. The quotes are necessary.


Function Code: Copy the following code into the Global Code and save it there.
Code: Select all
int xmouse_prev=xmouse;
int ymouse_prev=ymouse;
int xscroll_speed=0;
int yscroll_speed=0;

void mouseLook(char actor_background[30], char actor_crosshairs[30], char game_dimensions[4]) {
    if(xmouse!=xmouse_prev) { // If the horizontal mouse position has changed
        view.x+=(xmouse-xmouse_prev); // Moving the view along with the mouse
        getclone(actor_crosshairs)->x+=(xmouse-xmouse_prev); // Moving the crosshairs along with the view
        xscroll_speed=abs(xmouse_prev-xmouse);
        xmouse_prev=xmouse; // Setting value of xmouse_prev to xmouse for the next frame
                            }
    else if (xmouse<=20) { // If the mouse is at the extreme left of the screen
        view.x-=xscroll_speed; // Moving the view to the left
        getclone(actor_crosshairs)->x-=xscroll_speed; // Moving the crosshairs to the left
                         }
    else if (xmouse>=view.width-40) { // If the mouse is at the extreme right of the screen
        view.x+=xscroll_speed; // Moving the view to the left
        getclone(actor_crosshairs)->x+=xscroll_speed; // Moving the crosshairs to the right
                                    }


    if (strcmp(game_dimensions,"2D")==0&&view.x<=getclone(actor_background)->x-(getclone(actor_background)->width/2)) // If the game mode is 2D and view is at the left of the background image
        view.x=getclone(actor_background)->x-(getclone(actor_background)->width/2); // Stop moving left
    else if (strcmp(game_dimensions,"3D")==0&&view.x<=getclone(actor_background)->x-(getclone(actor_background)->width/2)+(1360-view.width)+xscroll_speed) // If the game mode is 3D and view is at the left of the background image
        // Jump to the right of the screen minus the xscroll_speed (that is the distance the screen would move in 1 frame)
        view.x=getclone(actor_background)->x+(getclone(actor_background)->width/2)-view.width-xscroll_speed-(1360-view.width)+10;
    else if (strcmp(game_dimensions,"2D")==0&&view.x+view.width>=getclone(actor_background)->x+(getclone(actor_background)->width/2)) // If the view is at the right of the background image
        view.x=getclone(actor_background)->x+(getclone(actor_background)->width/2)-view.width;  // Stop moving right
    else if (strcmp(game_dimensions,"3D")==0&&view.x+view.width>=getclone(actor_background)->x+(getclone(actor_background)->width/2)-(1360-view.width)-xscroll_speed) // If the game mode is 3D and view is at the right of the background image
        // Jump to the left of the screen plus the xscroll_speed (that is the distance the screen would move in 1 frame)
        view.x=getclone(actor_background)->x-(getclone(actor_background)->width/2)+xscroll_speed+(1360-view.width)-10;
 
    getclone(actor_crosshairs)->x=view.x+(view.width/2);


    if (strcmp(game_dimensions,"2D")==0&&view.x<=getclone(actor_background)->x-(getclone(actor_background)->width/2)) // If the game mode is 2D and view is at the left of the background image
        view.x=getclone(actor_background)->x-(getclone(actor_background)->width/2); // Stop moving right
    else if (strcmp(game_dimensions,"3D")==0&&view.x<=getclone(actor_background)->x-(getclone(actor_background)->width/2)+(768-view.width)) // If the game mode is 3D and view is at the left edge of the background image
        // Jump to the right of the screen minus the xscroll_speed (that is the distance the screen would move in 1 frame)
        view.x=getclone(actor_background)->x+(getclone(actor_background)->width/2)-view.width-xscroll_speed-(768-view.width)-10;
    else if (strcmp(game_dimensions,"2D")==0&&view.x+view.width>=getclone(actor_background)->x+(getclone(actor_background)->width/2)) // If the view is at the right edge of the background image
        view.x=getclone(actor_background)->x+(getclone(actor_background)->width/2)-view.width;  // Stop moving left
    else if (strcmp(game_dimensions,"3D")==0&&view.x+view.width>=getclone(actor_background)->x+(getclone(actor_background)->width/2)-(768-view.width)) // If the game mode is 3D and the view is at the right edge of the background image
        // Jump to the left of the screen plus the xscroll_speed (that is the distance the screen would move in 1 frame)
        view.x=getclone(actor_background)->x-(getclone(actor_background)->width/2)+xscroll_speed+(768-view.width)+10;
 
    getclone(actor_crosshairs)->x=view.x+(view.width/2);



    if(ymouse!=ymouse_prev) { // If the vertical mouse position has changed
        view.y+=(ymouse-ymouse_prev); // Moving the view along with the mouse
        getclone(actor_crosshairs)->y+=(ymouse-ymouse_prev); // Moving the crosshairs along with the view
        yscroll_speed=abs(ymouse_prev-ymouse);
        ymouse_prev=ymouse; // Setting value of ymouse_prev to ymouse for the next frame
                            }
    else if (ymouse<=20) { // If the mouse is at the top edge of the screen
        view.y-=yscroll_speed; // Moving the view up
        getclone(actor_crosshairs)->y-=yscroll_speed; // Moving the crosshairs up
                         }
    else if (ymouse>=view.height-40) { // If the mouse is at the bottom edge of the screen
        view.y+=yscroll_speed; // Moving the view down
        getclone(actor_crosshairs)->y+=yscroll_speed; // Moving the crosshairs down
                                    }
    if (strcmp(game_dimensions,"2D")==0&&view.y<=getclone(actor_background)->y-(getclone(actor_background)->height/2)) // If the game mode is 2D and view is at the top of the background image
        view.y=getclone(actor_background)->y-(getclone(actor_background)->height/2); // Stop moving up
    else if (strcmp(game_dimensions,"3D")==0&&view.y<=getclone(actor_background)->y-(getclone(actor_background)->height/2)+(768-view.height)) // If the game mode is 3D and view is at the top of the background image
        // Jump to the bottom of the screen minus the yscroll_speed (that is the distance the screen would move in 1 frame)
        view.y=getclone(actor_background)->y+(getclone(actor_background)->height/2)-view.height-yscroll_speed-(768-view.height)-10;
    else if (strcmp(game_dimensions,"2D")==0&&view.y+view.height>=getclone(actor_background)->y+(getclone(actor_background)->height/2)) // If the view is at the bottom of the background image
        view.y=getclone(actor_background)->y+(getclone(actor_background)->height/2)-view.height;  // Stop moving down
    else if (strcmp(game_dimensions,"3D")==0&&view.y+view.height>=getclone(actor_background)->y+(getclone(actor_background)->height/2)-(768-view.height)) // If the game mode is 3D and the view is at the bottom of the background image
        // Jump to the top of the screen plus the yscroll_speed (that is the distance the screen would move in 1 frame)
        view.y=getclone(actor_background)->y-(getclone(actor_background)->height/2)+yscroll_speed+(768-view.height)+10;
 
    getclone(actor_crosshairs)->y=view.y+(view.height/2);
                                                   }



Additional Options:
To begin the game with the screen centered in the original view position, paste the following code into the "view" actor's "Create" event. This is to avoid scrolling or an unexpected screen starting position when your game launches.
Code: Select all
// Initializing mouse position in variables
xmouse_prev=xmouse;
ymouse_prev=ymouse;



Example GED File: Attached - A sample simulated 3D game environment. The world map continues scrolling as though the player is moving "around" the screen.
Attachments
Mouse Look.zip
(824.86 KiB) Downloaded 244 times
Last edited by bamby1983 on Sat Mar 23, 2013 9:22 pm, edited 1 time in total.
bamby1983
 
Posts: 112
Joined: Tue Jul 31, 2012 11:36 pm
Score: 8 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby lcl » Sat Mar 23, 2013 12:04 pm

That mouse look function is really nice for 2D games!

Hey here's a way to improve it. :)
If you multiply the view moving values with the factor of (background.width / view.width) you can make it so that the
else if statements are not needed and the game is still able to scroll through the whole width of the background image.

See the old and new code compared.

Your code:
Code: Select all
if(xmouse!=xmouse_prev) { // If the horizontal mouse position has changed
    view.x+=(xmouse-xmouse_prev); // Moving the view along with the mouse
    Crosshairs.x+=(xmouse-xmouse_prev); // Moving the crosshairs along with the view
    xmouse_prev=xmouse; // Setting value of xmouse_prev to xmouse for the next frame
                        }
else if (xmouse<=20) { // If the mouse is at the extreme left of the screen
    view.x-=10; // Moving the view to the left
    Crosshairs.x-=10; // Moving the crosshairs to the left
                    }
else if (xmouse>=view.width-40) { // If the mouse is at the extreme left of the screen
    view.x+=10; // Moving the view to the left
    Crosshairs.x+=10; // Moving the crosshairs to the left
                                }

My version of it:
Code: Select all
if(xmouse!=xmouse_prev) { // If the horizontal mouse position has changed
    view.x+=(xmouse-xmouse_prev)*(Background.width/view.width); // Moving the view along with the mouse
    Crosshairs.x+=(xmouse-xmouse_prev)*(Background.width/view.width); // Moving the crosshairs along with the view
    xmouse_prev=xmouse; // Setting value of xmouse_prev to xmouse for the next frame
                        }

Try replacing my code over yours and you'll see how it works. I hope this was helpful! :)
(I also suggest you to put up a demo with the function used instead of the code in view's draw actor event. Would look prettier. :) )
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby bamby1983 » Sat Mar 23, 2013 8:47 pm

That's a pretty neat way of maintaining a reasonable scroll speed based on the world:view size ratio. I'm not sure whether it would work at the edge of the screen, though. My code calculates the movement speed based on the mouse position relative to the previous frame. If the mouse reaches the edge of the screen and stays there, the relative motion would be zero, so there would be no motion. The background and view size are constants and act as a pretty neat multiplying factor, but initial part of the equation would be zero. :(
bamby1983
 
Posts: 112
Joined: Tue Jul 31, 2012 11:36 pm
Score: 8 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby lcl » Sat Mar 23, 2013 8:54 pm

Did you try it? For me it worked just fine.
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby bamby1983 » Sat Mar 23, 2013 9:29 pm

lcl wrote:Did you try it? For me it worked just fine.

It worked wonderfully for 2D - MUCH better than the code I wrote. It even allowed me to vary the scrolling speed after the cursor hit the edge of the screen! It didn't work for 3D, though.

I'm curious as to how this code works.

Code: Select all
if(xmouse!=xmouse_prev) { // If the horizontal mouse position has changed
    view.x+=(xmouse-xmouse_prev)*(Background.width/view.width); // Moving the view along with the mouse
    Crosshairs.x+=(xmouse-xmouse_prev)*(Background.width/view.width); // Moving the crosshairs along with the view
    xmouse_prev=xmouse; // Setting value of xmouse_prev to xmouse for the next frame
                        }


If the cursor is at the edge of the screen, then xmouse should equal to xmouse_prev, so the value of view.x+=...... should equal to 0. How is this not happening and how does the ratio of the background and view width influence this outcome?
bamby1983
 
Posts: 112
Joined: Tue Jul 31, 2012 11:36 pm
Score: 8 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby GEuser » Sun Mar 24, 2013 5:12 am

Thanks bamby. Looking forward to seeing what you put up.
GEuser
 
Posts: 204
Joined: Thu Jan 05, 2012 3:08 pm
Score: 19 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby lcl » Sun Mar 24, 2013 7:38 pm

bamby1983 wrote:It even allowed me to vary the scrolling speed after the cursor hit the edge of the screen!

No it didn't. :D The trick is here: the value the view has to be moved is calculated in a way that the view will reach its
max position at the same time when the mouse reaches the edge of the window. :)

For that, I added the *(Backgound.width/view.width) part to the code.
The result of the fraction is the amount of pixels the view has to move when the mouse moves 1 pixel.

By multiplying the mouse x axis movement with this value and then moving the view by the result, it is possible
the see the whole 2D background image just by moving mouse form one edge of the screen to the other one. :)

bamby1983 wrote:If the cursor is at the edge of the screen, then xmouse should equal to xmouse_prev, so the value of view.x+=...... should equal to 0.

And it is equal to 0. And that is what we want, because with my code, the edge of the background has been reached as the mouse has reached the edge of the view. :)
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby bamby1983 » Sun Mar 24, 2013 8:32 pm

I think I understand. The view.x calculated is 0 with respect to the screen/mouse co-ordinates and not with respect to the game center! I thought assigning view.x to a value of zero would mean that it was zero with respect to the game center. I didn't realize that GE automatically converts screen co-ordinates to game center co-ordinates automatically like that (isn't that what's happening here)?

Also, I did a little experiment and realized that the mouse never reaches the end of the screen until the background image has also ended. That removes the necessity for scroll control at the edges! This is probably because of the width ratio you coded in. However, what this means is that the scroll speed will vary depending on the background size. We can work around that by ensuring that all background are the same size as the largest one so that the scroll speed is constant throughout the game. There would be additional coding required to make the view jump to the other side in a simulated 3D game if the view size is smaller. This can be done dynamically to make it a reusable function.
bamby1983
 
Posts: 112
Joined: Tue Jul 31, 2012 11:36 pm
Score: 8 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby lcl » Sun Mar 24, 2013 8:55 pm

bamby1983 wrote:I think I understand. The view.x calculated is 0 with respect to the screen/mouse co-ordinates and not with respect to the game center! I thought assigning view.x to a value of zero would mean that it was zero with respect to the game center. I didn't realize that GE automatically converts screen co-ordinates to game center co-ordinates automatically like that (isn't that what's happening here)?

Nope. Notice that it is view.x += .... not view.x = ...
When the ... part is 0, view.x is not being set to 0, instead view.x is being increased by 0, so it's just staying where it is. :)

bamby1983 wrote:Also, I did a little experiment and realized that the mouse never reaches the end of the screen until the background image has also ended. That removes the necessity for scroll control at the edges! This is probably because of the width ratio you coded in.

That was the reason I added that multiplying by the width ratio. As I said:
me wrote:The trick is here: the value the view has to be moved is calculated in a way that the view will reach its
max position at the same time when the mouse reaches the edge of the window.
:)

bamby1983 wrote:However, what this means is that the scroll speed will vary depending on the background size.

Yes it does, I know. But I think it's still better than making the view move with some predefined constant speed when the mouse has reached the edges of the screen. :wink:

bamby1983 wrote:There would be additional coding required to make the view jump to the other side in a simulated 3D game if the view size is smaller. This can be done dynamically to make it a reusable function.

How would you do this? The mouse would still be in the edge of the screen and thus not able to move to that direction, so after turning one whole revolution, the rotating would act differently (if one doesn't change the direction of rotating, in which case the mouse would have some space to move to again).
User avatar
lcl
 
Posts: 2339
Joined: Thu Mar 25, 2010 5:55 pm
Location: Finland
Score: 276 Give a positive score

Re: Custom Functions for GE: Easy-to-Use Resuable Code

Postby bamby1983 » Mon Mar 25, 2013 12:02 am

You're right, I didn't think of that. Changing the direction may not help coz the player would still be trying to move his mouse in the same position, which is at the edge. :(
bamby1983
 
Posts: 112
Joined: Tue Jul 31, 2012 11:36 pm
Score: 8 Give a positive score


Return to Resources

Who is online

Users browsing this forum: No registered users and 1 guest

cron