Week 13

Making a Simple “Platform” Game

Part 1 – platform “landscape” with horizontal scrolling

platforms is an array of simple objects with x, y and w (width) fields. All platforms are 10 pixels thick (see draw()). Platforms are “shifted” by offset when we draw them. When new platforms are needed (as the offset increases), we create new platforms. Old platform objects are removed as they scroll off the left edge of the canvas.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

// Game example

// A platform game, horizontal scrolling

// first, let's make a generative "landscape" with platforms

// each platform will be an object with an x, y, and w parameter

varplatforms=[];

// to scroll, we will increment offset. Everything is shifted left by offset

varoffset=0;

functionnewPlatform(px,py,pw){

return{x:px,y:py,w:pw};

}

functionsetup(){

createCanvas(600,300);

platforms.push(newPlatform(600,200,200));

}

// compute the location of the right end of a platform

functionplatRight(p){

returnp.x+p.w;

}

// return the last platform object

functionplatLast(){

returnplatforms[platforms.length-1];

}

functiondraw(){

background("lightblue");

fill("green");

stroke("green");

rect(0,height-50,width,50);// the ground

fill(0);

stroke(0);

for(vari=0;i<platforms.length;i++){

varp=platforms[i];

rect(p.x-offset,p.y,p.w,10);

}

// if first platform is offscreen to left, remove it

if(platforms.length>0&&platRight(platforms[0])<offset){

platforms.shift();

}

// if last platform is totally within canvas, make a new one

if(platRight(platLast())-offset<width){

varp=newPlatform(platRight(platLast()),// start location

random(50,225),// height of new platform

200);// all platforms have width 200 for now

platforms.push(p);// add to our array of platforms

}

text(platforms.length.toString()+" platforms",10,30);

// move the "landscape"

offset+=1;

}

functionmousePressed(){

}

functionkeyPressed(){

}

Part 2 – adding a “mario” character

We always draw the character in the middle of the canvas, so we only worry about the vertical (Y) coordinate. We need to find which platform is currently in the middle of the screen, so we do a linear search to find it. Then we move the “mario” based on whether it is above, on, or below the relevant platform. The character automatically “wraps around” when it falls, which means we need no interaction to do some testing.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

// Game example, part 2, see comments starting with //2

// A platform game, horizontal scrolling

// first, let's make a generative "landscape" with platforms

// each platform will be an object with an x, y, and w parameter

//2 in part 2, we add a "mario"

varplatforms=[];

varmarioY=0;//2 the height of our "mario"

// to scroll, we will increment offset. Everything is shifted left by offset

varoffset=0;

functionnewPlatform(px,py,pw){

return{x:px,y:py,w:pw};

}

functionsetup(){

createCanvas(600,300);

platforms.push(newPlatform(600,200,200));

}

// compute the location of the right end of a platform

functionplatRight(p){

returnp.x+p.w;

}

// return the last platform object

functionplatLast(){

returnplatforms[platforms.length-1];

}

functiondraw(){

background("lightblue");

fill("green");

stroke("green");

rect(0,height-50,width,50);// the ground

fill(0);

stroke(0);

for(vari=0;i<platforms.length;i++){

varp=platforms[i];

rect(p.x-offset,p.y,p.w,10);

}

// if first platform is offscreen to left, remove it

if(platforms.length>0&&platRight(platforms[0])<offset){

platforms.shift();

}

// if last platform is totally within canvas, make a new one

if(platRight(platLast())-offset<width){

varp=newPlatform(platRight(platLast()),// start location

random(50,225),// height of new platform

200);// all platforms have width 200 for now

platforms.push(p);// add to our array of platforms

}

text(platforms.length.toString()+" platforms",10,30);

//2 move and draw the "mario"

//2 which platform is current? linear search (!) through platforms

varpindex=0;

varmarioX=width/2;

while(platRight(platforms[pindex])-offset<marioX){

pindex+=1;

}

//2 now pindex is index of the platform in the middle of canvas

//2 find the platform height

varpy=platforms[pindex].y;

//2 show some debugging information for now

text("pindex "+pindex+" py "+py,10,50);

//2 if we are above it, fall toward it, but do not go past it

if(marioY<=py){

marioY=min(py,marioY+1);

}else{//2 if we are below it, fall to ground

marioY=min(height,marioY+1);

}

//2 wrap around, "fall from sky" again if we "die"

if(marioY>=height){

marioY=0;

}

//2 draw the "mario"

fill("brown");

stroke("brown");

rect(marioX,marioY-20,20,20);

// move the "landscape"

offset+=1;

}

functionmousePressed(){

}

functionkeyPressed(){

}

Part 3 – Adding “jump” command and simple physics for falling

To implement jumping, we start by adding marioDy, which is the velocity of the “mario” character. We have to add more logic for controlling position, but now the “jump” command is simply setting marioDy to -10 to give it an upward velocity. (See line 113.)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

// Game example, part 3, see comments starting with //3

// A platform game, horizontal scrolling

// first, let's make a generative "landscape" with platforms

// each platform will be an object with an x, y, and w parameter

//2 in part 2, we add a "mario"

//3 in part 3, we add a "jump" command. The jump will give "mario" a

//3 vertical velocity.

varplatforms=[];

varmarioY=0;//2 the height of our "mario"

varmarioDy=0;//3 the vertical velocity of "mario"

// to scroll, we will increment offset. Everything is shifted left by offset

varoffset=0;

functionnewPlatform(px,py,pw){

return{x:px,y:py,w:pw};

}

functionsetup(){

createCanvas(600,300);

platforms.push(newPlatform(600,200,200));

}

// compute the location of the right end of a platform

functionplatRight(p){

returnp.x+p.w;

}

// return the last platform object

functionplatLast(){

returnplatforms[platforms.length-1];

}

functiondraw(){

background("lightblue");

fill("green");

stroke("green");

rect(0,height-50,width,50);// the ground

fill(0);

stroke(0);

for(vari=0;i<platforms.length;i++){

varp=platforms[i];

rect(p.x-offset,p.y,p.w,10);

}

// if first platform is offscreen to left, remove it

if(platforms.length>0&&platRight(platforms[0])<offset){

platforms.shift();

}

// if last platform is totally within canvas, make a new one

if(platRight(platLast())-offset<width){

varp=newPlatform(platRight(platLast()),// start location

random(50,225),// height of new platform

200);// all platforms have width 200 for now

platforms.push(p);// add to our array of platforms

}

text(platforms.length.toString()+" platforms",10,30);

//2 move and draw the "mario"

//2 which platform is current? linear search (!) through platforms

varpindex=0;

varmarioX=width/2;

while(platRight(platforms[pindex])-offset<marioX){

pindex+=1;

}

//2 now pindex is index of the platform in the middle of canvas

//2 find the platform height

varpy=platforms[pindex].y;

//3 show some debugging information for now

text("pindex "+pindex+" py "+py+" Dy "+marioDy,10,50);

//2 if we are above it, fall toward it, but do not go past it

if(marioY<=py){

marioY=min(py,marioY+marioDy);//3 change Y by Dy

}else{//2 if we are below it, fall to ground

//3 if dY is negative, we could "punch through" a platform from below

//3 to avoid this, once we are below a platform, force Dy non-negative

if(marioDy<0){

marioDy=0;

}

marioY=min(height,marioY+marioDy);

}

//2 wrap around, "fall from sky" again if we "die"

if(marioY>=height){

marioY=0;

marioDy=0;

}

//2 draw the "mario"

fill("brown");

stroke("brown");

rect(marioX,marioY-20,20,20);

// move the "landscape"

offset+=1;

//3 accelerate "mario" with gravity

marioDy=marioDy+1;

}

functionmousePressed(){

}

functionkeyPressed(){

marioDy=-10;//3 velocity set to up when key is pressed

}

Here is the sketch so far

Note that Dy (marioDy) continues to increase when the character is on a platform, and the character does not fall in a plausible way from the platform, so there is more work to do here.