samedi 29 mai 2021

Shake my chicken with Pico8...

 

 
Fig.1 #Pixcode Shake
The syntax of the code does not correspond to a particular language. This "code" just allows to understand the process to follow.
 
 

 Fig.2 Do it with Pico8
 
 



--Shake my chicken!

function _init()
intensity=0
end

function _update()
    cls()
    if btnp(❎) then
        intensity=5
    end
end

function _draw()
    shake()
    spr(1+(time()*5%4),60,60)
   
    print(intensity,0,10,15)
    print("press ❎ to shake",35,80,15)
end

function shake()
    local shakex=(rnd({-intensity,intensity}))
    local shakey=(rnd({-intensity,intensity}))
    print(shakex,0,17,15)
    print(shakey,0,24,15)
    intensity*=0.9
    if (intensity<=0.5) intensity=0


    camera(shakex,shakey)


end

mardi 18 mai 2021

Collision Circle/Square or Rectangle with Pico8


1- Collision circle/square with sine and cosine just for fun!
 

 

Sometimes I do useless stuff just for fun and to get my brain fired up, when simpler solutions exist!!! If you had to choose only one solution, the second one is the most reasonable ;-) 

 

#pixcode 1: Detect the corners of a square
 

 #pixcode 2: There is a collision, but D > 0, so the collision is not detected. We need to check the vertical and horizontal alignment.


 function _init()
--circle center
x1=90
y1=60

--square center
x2=60
y2=80

d=10 --square side/2
r=10 --radius

end

function _update()

--controls
if (btn(0)) x1-=1
if (btn(1)) x1+=1
if (btn(2)) y1-=1
if (btn(3)) y1+=1

--calculate oc
a=abs(x1-x2)
b=abs(y1-y2)
oc=sqrt(a^2+b^2)

--calculate sine and cosine
cosa=b/oc
sina=a/oc

--calculate di. The value 0.7071 is only for a square
if cosa <= 0.7071 then
    di=d/sina
else di=d/cosa
end

--check collision with a corner or middle edge
if (oc<=(r+di)) then
    corner=1
else corner=0
end

--check the collision with edges
if a<=d and b<=(r+d) then
    touchh=1
else touchh=0
end

if b<=d and a<=(r+d) then
    touchv=1
else touchv=0
end

--calculate Deltad (not necessary)
deltad=oc-(r+di)

end--end update


function _draw()
cls()

--draw points
pset(x1,y1,8) --circle center
pset(x2,y2,10) --square center

--circle
circ(x1,y1,r,8)
--square
rect((x2-d),(y2-d),(x2+d),(y2+d),10)


--collision detection
if  corner==1 or (touchh==1 or touchv==1) then
    rectfill((x2-d),(y2-d),(x2+d),(y2+d),8)
end

--line circle center to square center
line(x1,y1,x2,y2,14)


end

 

 

2- Collision circle/rectangle or square (easy!)

#PIxcode 3: Check collison with corners of a rectangle or a square

This method is the easiest ->


pico-8 cartridge // http://www.pico-8.com
version 30
__lua__


function _init()
--circle center and radius
x1=90
y1=60
r=10
--rectangle center, width and height. For a square w=h
x2=60
y2=80
w=40
h=20

end--

function _update()
--controls
if (btn(0)) x1-=1
if (btn(1)) x1+=1
if (btn(2)) y1-=1
if (btn(3)) y1+=1

--calculate dh,dv,
dh=abs(x1-x2)
dv=abs(y1-y2)
distx=(dh-(w/2)) --dx
disty=(dv-(h/2)) --dy
distr=distx^2+disty^2 --d

--check collision with corners
if distr<=r^2 then
    collision=1
else collision=0
end

--check the collision with horizontal edges
if dh<=(w/2) and dv<=(r+(h/2)) then
    touchh=1
else touchh=0
end
--check the collision with vertical edges
if dv<=(h/2) and dh<=(r+(w/2)) then
    touchv=1
else touchv=0
end

end



function _draw()
cls()
--draw points
pset(x1,y1,8) --circle center
pset(x2,y2,10) --square center

--circle
circ(x1,y1,r,8)
--square
rect((x2-(w/2)),(y2-(h/2)),(x2+(w/2)),(y2+(h/2)),10)


--collision detection
if  collision==1 or (touchh==1 or touchv==1) then
    rectfill((x2-(w/2)),(y2-(h/2)),(x2+(w/2)),(y2+(h/2)),8)
end

--line circle center to square center
line(x1,y1,x2,y2,14)

end



mardi 23 juin 2020

Gamemaker Studio 2: Simulate a light effect around a sprite (player, fire, explosion...).



The player is followed by the obj_playerLight

Hi all!

This light effect is a kind of hole into a dark surface over layers of your game.
This surface can be placed whereever you want: over all layers or between two layers.
You can set the darkness intensity with alpha between a value from 0 (no darkness) to 1 (totaly black).

We are going to create a light object associated to a sprite. This sprite is a simple white circle (Fig. 1). But you can use an animated sprite (Fig. 2).




  Fig. 1 obj_playerLight    Fig. 2 obj_playerLight2

If you use a simple white circle, it would be interesting to make it animated by increasing and decreasing the radius with the function draw_sprite_ext.


obj_playerLight: Create, Step and draw event.







obj_playerLight2: Create, Step and draw event.







Thanks for reading!




Pssst! Play my game!!! Ghost'n Brothers 1bit (free) and Ghost'n Brothers (paid version). Only on iOS.








samedi 20 juin 2020

Do things with draw_line function: connected lines

This tutorial is for beginners to learn how to use draw_line and draw_point functions and arrays. If you like math, add cosines and sines to do nice things just for fun!




We will create a broken line with the draw_line_color and draw_point_color functions.

The function draw_line_color(x0, y0, x1, y1, c_green, c_green) has 6 arguments.
The first 4 correspond to the coordinates of the points (x0, y0) and (x1, y1) between which a line segment will be drawn.

With each click on the screen, a point will be created which will be connected by a line segment to the previous one.
For this, we will have to use a "loop for" with the "draw_line" function.

So I have created 4 arrays AX, AY, BX, BY to record the coordinates xn, yn, xn+1, yn+1.

Fig. 1, shows the organization of the x and y coordinates in the arrays.


Fig. 1: 4 arrays to store coordinates


You will notice that we always have, for all the arrays, the coordinates of the previous point and the next point at the same index!
Everything happens as if the arrays A were shifted with a point of delay on the arrays B.

For an index n, we have the coordinates of points n on A and "n+1" on B except for n=0, where the coordinates of this first point is stored in BX and BY.
This shift between A and B is done simply by transferring the values "n - 1" of B to the index n of A which are opposite the values n + 1 of B. Simple!!!!

Let's go to the code...

Event Create (see Fig. 2).

Fig. 2: Event Create


Event Draw.
The first thing to do is to store the coordinates of the first point. This is the role of the first condition if.
It will only be used once, hence the use of the variable "next_point = false" to be able to skip this condition when we do the following. "next_point" will then become "true" (see Fig. 3 & 4).





Fig. 3: Event Draw part 1


Fig. 4: Event Draw part 2


An if condition is inserted between the first and the third one. It will check the state of the left mouse button and switch "next_point" to "true" if the button is released.

If you don't do this and change "next_point" to "true" at the end of the first if condition, gamemnaker will immediately move to the next condition. Do the test, you'll see that it won't work correctly with a variable n that changes to "1" at the first mouse click!

The third condition will allow you to store all of the following (n > 0). It will allow you to store the coordinates of a new point in BX & BY and transfer the value of "n - 1" from BX & BY to AX & AY at index "n".


The fourth condition is related to the display...if n = 0, BX and BY contain the coordinates of your first point while AX and AY are empty. Gamemaker cannot display a line with a single point so we simply ask it to display the point with "draw_point".

Finally, if "n" is different from 0, then you can draw a line...A for loop allows to scan at each step the values of the 4 arrays. In this loop, I use var i = 1 instead of 0 because at index n = 0, AX and AY are set to 0, the origin of your room! This avoids a line between the coordinates (0, 0) and your first point.

That's all!

Draw_line and draw_point allow you to do nice things with math... Now you can try to do something like these animated lines or an animated square...



















ScreenShake - Gamemaker Studio 2 - Methode 1 & 2 - Tuto fr complet

Deux méthodes pour créer un tremblement d'écran (screenshake).

Méthode 1: L'objet est créé à la demande, puis détruit une fois son rôle terminé. Il faudra recréer cette instance à chaque fois que cela sera nécessaire.

Méthode 2: L'objet créé sera juste désactivé en fin d'action, puis sera réactivé en fonction des besoins







GameMakerStudio 2: GUI Layer and multi-touch: Create 3 buttons (left, right, and jump) for your iOS game.


Last Update:  Feb, 2021
Released Button issue has been fixed.

Using Keyboard to control your sprite is relatively easy to implement with the function keyboard_check(key). But if you want to run your game on your mobile device, you need to implement multi touch buttons…You can find many tutorials about GUI layer and buttons on the web, but  i’ve not been able to find anything about iOS development so it  is what i’m going to try to do!

Have you ever heard about Downwell and the Gun Boots? Downwell is a very polished game. Control buttons are very responsive and fast. 3 buttons: Left, Right, and a dual action button to jump and shoot. We will try to reproduce the same mechanics except the third.  The last button will be only associated with the jump movement.


Downwell by Ojiro Fumoto @moppin


The big question is...

What is the best way to fix the position of the control buttons on the screen? If you just place the instance of your button object within the room, when the camera moves, the button moves too!

You can use 2 variables to record the position of the camera view X and Y. Then in the step event, you can set the position X and Y of all buttons relative to the camera like this:

(step event)

Xbutton = Xcam + Xoffset

So, they will move together but not really at the same time!!! If you do that, buttons will be always visible, but they won’t be fixed! You’ll see a little delay between the move of the camera and the buttons because GM has to recalculate continuously their position…wrong way!

That’s why we need to use the GUI Layer and the DrawGUI event!


Things we need to know about GUI Layer.

- All DrawGUI event won’t be affected by the view position, scale and rotation

- The coordinates do not change. (0, 0) is always on the top left of the application surface or display.

- By default, GUI layer is 1:1 with the application surface…

- GUI layer can be scaled, resized and positioned to adapt to any device size with only a few lines of code, and that as long as you base your calculations around the device screen aspect ratio you can't go far wrong.

Want to be an expert? Read the yoyogames documentation!!!


It’s time to get to the heart of the subject…



Fig. 1: Room, Camera_view, and GUI layer. To the right, see the Touch Area (TA) bounded by coordinates x1, y1 and x2,y2.


You need 3 sprites. One for the left button and so on.

Then we need to create 3 objects with these sprites. One for each button.

- Create an object to manage all objects buttons (creation, position, behavior…) and place it into the room (Fig. 2).



Fig. 2: obj_Control_GUI - Create Event

- For me, obj_Control_GUI create the buttons on the layer "BTN". Then, be sure to position them above the Touch Area (Fig. 1 & 5).




Fig. 5: fix the object button over the touch area.


- Initialize variables you may need to do something when buttons will be pressed.


Well, in the the Step event, we also need a function to tell Gamemaker to check if something happens into the Touch Area bounded by (x1, y1) and (x2, y2) of the GUI Layer (Fig. 1). If true…do something!

So we use the functions :

device_mouse_check_button_pressed(i, mb_any) to detect if you touch the screen and point_in_rectangle(device_mouse_x_to_gui(i), device_mouse_y_to_gui(i), x1, y1, x2, y2) to tell GM where is situated the active Touch Area.

 



Fig. 3: obj_Control_GUI - Step Event - Check if BTN is pressed




 
 
Fig. 4: obj_Control_GUI - End Step Event - Check if BTN is released

Update: We do not specify again the bounded area to check if BTN is released!


What else…

1 -  If you want a real multi-touch, you have to use a for loop to assign dynamically an id (0, 1, or 2) for each button. If you don’t do that…it won’t work! 

2 - If you use (i, mb_left) instead of (i, mb_any) with the first function, the button mechanics will be laggy and your game unplayable!

3 - If your game has only 2 buttons, you can use (0, mb_left) for the first button and (0, mb_right) for the second…but don’t forget to disable double-clicking assigned to the right button by default in GM. So, use device_mouse_dbclik_enable(false).

 I would like to thank @chinykian the creator of Serious Scramblers for this tip!


Where is the button? 

The touch area is invisible and sometimes bigger than your sprite button. If the touch area is too small, the player can miss the button when he touches the screen so don’t hesitate to make a large touch area.

Well, but now we need to fix the object of your button above the touch area (Fig. 5).

Fig. 6: DrawGUI event.

So, open each object button (Fig. 6) and create a DrawGUI event. Then use the function draw_self(); to fix it on the GUI layer, Don’t forget to create a Draw event and leave it blank! If not, all buttons will be cloned. Half of them will be fixed and the other part won’t be fixed.

Champagne!


Now, let’s see the result (Fig. 7)…


Fig. 7: Game test




Thank you for reading!!! Follow me on twitter @ouzzgame.




Shake my chicken with Pico8...

      Fig.1 #Pixcode Shake The syntax of the code does not correspond to a particular language. This "code" just allows to underst...