Week17
1.音效
根据week3的内容加上跳跃,bgm,以及死亡音效。
import ddf.minim.*;
Minim minim;
AudioPlayer bgm,jump,gameover;
在setup设定的部分加上以下程式码,可以载入三个档案。
minim = new Minim(this);
gameover = minim.loadFile("gameover.wav");
jump = minim.loadFile("jump.mp3");
bgm = minim.loadFile("bgm.mp3");
在keyPressed的函式中加入以下程式码,能够在跳跃时发出相对音效。
jump.rewind();
jump.play();
在死亡时bgm会暂停,且发出死亡音效。
bgm.pause();
gameover.play();
2.给板子加上上下移动的速度
hboardy[i]+=md[i];
if(hboardy[i]<110) md[i]=abs(md[i]);
if(hboardy[i]>260) md[i]=-abs(md[i]);
以上程式码能让给方块y方向的速度,且控制在110-260范围内,超过范围速度方向会变。
3.跳上板子后会跟着移动
if(onhBoard==true) usery+=md[hboardID];
3.贴图
PImage img1,img2,img3,img4,img5,img6,img7;
在setup部分载入图片
img1=loadImage("bg.jpg");
img2=loadImage("gg.png");
img3=loadImage("good.png");
img4=loadImage("bg2.jpg");
img5=loadImage("bg3.png");
img6=loadImage("start.jpg");
img7=loadImage("block.png");
最后在各个需要的地方贴上贴图
image(img6,0,0,600,400);
image(img1,0,0,600,400);
4.字型处理
PFont myFont;
载入正黑体
myFont = createFont("微軟正黑體",30);
最后用text指令完成输入
5.最终程式码
import ddf.minim.*;//音效
Minim minim;//音效
AudioPlayer bgm,jump,gameover;//音效及三个音档
PImage img1,img2,img3,img4,img5,img6,img7;//贴图图片
PFont myFont;//字型
float []badx,bubblex,bubbley,boardx,boardy,boardw,hboardx,hboardy,hboardw,trix,triy,rx,ry,md,mdt;
int now,score,now2;
int boardID=0;
int hboardID=0;
int rID=0;//部分变数
void setup(){
size(600,400);
myFont = createFont("微軟正黑體",30);//字型
img1=loadImage("bg.jpg");//贴上的图片
img2=loadImage("gg.png");
img3=loadImage("good.png");
img4=loadImage("bg2.jpg");
img5=loadImage("bg3.png");
img6=loadImage("start.jpg");
img7=loadImage("block.png");
minim = new Minim(this);
gameover = minim.loadFile("gameover.wav");
jump = minim.loadFile("jump.mp3");
bgm = minim.loadFile("BGMG.mp3");//音效
textSize(40);
badx=new float[1200];//陷阱x
badx[0]=350+250;
for(int i=1;i<1200;i++){
if(i%5==0 || i%8==0 || i%11==0) {badx[i]=badx[i-1]+random(200,300);}//不让陷阱太密集
else {badx[i]=badx[i-1]+random(50,55);}
}
boardx=new float[200];//板子x
boardx[0]=380+250;
for(int i=1;i<200;i++){
boardx[i]=boardx[i-1]+random(360,440);
}
boardy=new float[200];//板子y
boardy[0]=260;
for(int i=1;i<200;i++){
if(boardy[i-1]>=270){boardy[i]=boardy[i-1]-20;}//防止板子太高或太低
else if(boardy[i-1]<=230){boardy[i]=boardy[i-1]+20;}
else boardy[i]=boardy[i-1]+random(-20,10);
}
boardw=new float[200];//板子宽度
boardw[0]=140;
for(int i=1;i<200;i++){
boardw[i]=boardw[i-1]+random(-20,10);
if(boardw[i-1]<=80){boardw[i]=boardw[i-1]+30;}
}
hboardx=new float[190];//更高的板子x
//hboardx[0]=boardx[2]+160;
for(int i=0;i<190;i++){
//hboardx[i]=hboardx[i-1]+random(300,380);
hboardx[i]=boardx[i+2]+random(200,210);
}
trix=new float[360];//板子底下带的陷阱
for(int i=0;i<360;i++){
if(i%2==0) trix[i]=hboardx[i/2]+50;
else trix[i]=hboardx[(i-1)/2]+50+50;
}
hboardy=new float[190];//更高的板子y
hboardy[0]=150;
for(int i=1;i<190;i++){
if(hboardy[i-1]>=170){hboardy[i]=hboardy[i-1]-20;}
else if(hboardy[i-1]<=120){hboardy[i]=hboardy[i-1]+20;}
else hboardy[i]=hboardy[i-1]+random(-20,10);
}
triy=new float[360];//板子下的陷阱y
triy[0]=150+20;
for(int i=1;i<360;i++){
if(i%2==0) triy[i]=hboardy[i/2]+20;//贴近板子
else triy[i]=hboardy[(i-1)/2]+20;
}
hboardw=new float[190];//更高的板子宽度
hboardw[0]=150;
for(int i=1;i<190;i++){
hboardw[i]=hboardw[i-1];
}
rx=new float[180];//距离较远时会出现的小板子x
for(int i=0;i<180;i++){
rx[i]=boardx[i+8]+boardw[i+8]+10;
}
ry=new float[280];//距离较远时会出现的小板子y
for(int i=0;i<280;i++){
ry[i]=170;
}
md=new float[190];//板子上下移动的速度
for(int i=0;i<190;i++){
md[i]=random(0.3,0.6);
}
mdt=new float[360];//陷阱上下移动的速度
for(int i=0;i<360;i++){
mdt[i]=(md[i/2]/0.4001)*0.1335;
}
bubblex=new float[10];//方块身后气泡
bubbley=new float[10];
for(int i=0;i<10;i++){
bubblex[i]=0;
bubbley[i]=300;
}
}
float usery=300, vy=0, bgx=0, speed=0;
//md=0.4001,mdt=0.1335;
boolean gameOver=false;
boolean onBoard=false;
boolean onhBoard=false;
boolean onr=false;
int condition=0;
int wait=0;
void mousePressed(){///場景切換
if (mouseButton == LEFT) condition=1;
}
void draw(){
if(condition==0){//初始画面
image(img6,0,0,600,400);
fill(255);
text("按下滑鼠左鍵開始遊戲",150,50);
text("上鍵跳躍 下鍵無敵",170,350);
textFont(myFont);
wait=millis()/1000;
}
if(condition==1){
if(gameOver && hacking==false) bgm.pause();//游戏结束则bgm暂停
else bgm.play();//否则正常播放
if(score>=0 && score<30) image(img1,0,0,600,400);//到一定阶段会更换背景
if(score>=20 && score<40) image(img4,0,0,600,400);
if(score>=40) image(img5,0,0,600,400);
speed=(score/4)*0.3;//速度会随分数增加而增加
bgx=bgx+3.3+speed;
fill(#F5ADCF);
for(int i=0;i<1200;i++){
now=i;
if(collision()) gameOver=true;//碰到陷阱则游戏结束
triangle(badx[i]-bgx,310,badx[i]-25-bgx,350,badx[i]+25-bgx,350);
}
fill(#F5ADCF);
for(int i=0;i<360;i++){
now2=i;
if(collision2()) gameOver=true;
triangle(trix[i]+25-bgx,(triy[i]+=mdt[i])+40,trix[i]-bgx,triy[i]+=mdt[i],trix[i]+50-bgx,triy[i]+=mdt[i]);
if(triy[i]<130) mdt[i]=abs(mdt[i]);//控制陷阱在一定范围内
if(triy[i]>280) mdt[i]=-abs(mdt[i]);
}
fill(#003E6C); rect(0,350,600,400);//地板
fill(#FFEC17);
image(img7,150,usery,50,50);//玩家角色以及贴图
if(jumping){//跳跃改变y以及加速度
usery+=vy;
vy+=0.98/2.5;
if(usery>300){//停留在地上
jumping=false;
usery=300;
}
}
fill(#AD0051);
for(int i=0;i<200;i++){
rect(boardx[i]-bgx,boardy[i],boardw[i],20);
if(boardID==i){
if(onBoard==true && (boardx[i]+boardw[i]<150+bgx) ){
onBoard=false;jumping=true;
}
}
if(jumping && usery+50<boardy[i] && usery+50+vy>boardy[i] && boardx[i]<150+50+bgx && 150+bgx<boardx[i]+boardw[i]){
usery=boardy[i]-50;vy=0;jumping=false;onBoard=true;boardID=i;//方块停留在板子上
}
}
fill(#AD0051);
for(int i=0;i<190;i++){
hboardy[i]+=md[i];//让板子上下移动
rect(hboardx[i]-bgx,hboardy[i],hboardw[i],20);
if(hboardy[i]<110) md[i]=abs(md[i]);
if(hboardy[i]>260) md[i]=-abs(md[i]);//限制板子移动在一个范围内
if(hboardID==i){
if(onhBoard==true && (hboardx[i]+hboardw[i]<150+bgx) ){
onhBoard=false;jumping=true;
}
}
if(jumping && usery+50<hboardy[i] && usery+50+vy>hboardy[i] && hboardx[i]<150+50+bgx && 150+bgx<hboardx[i]+hboardw[i]){
usery=hboardy[i]-50;vy=0;jumping=false;onhBoard=true;hboardID=i;
}
}
if(onhBoard==true) usery+=md[hboardID];//角色能跟着板子上下移动
fill(#AD0051);
for(int i=0;i<180;i++){//在小板子上
rect(rx[i]-bgx,ry[i],70,20);
if(rID==i){
if(onr==true && (rx[i]+70<150+bgx) ){
onr=false;jumping=true;
}
}
if(jumping && usery+50<ry[i] && usery+50+vy>ry[i] && rx[i]<150+50+bgx && 150+bgx<rx[i]+70){
usery=ry[i]-50;vy=0;jumping=false;onr=true;rID=i;
}
}
for(int i=9;i>0;i--){//身后的气泡
bubblex[i]=bubblex[i-1];
bubbley[i]=bubbley[i-1];
fill(#FFF586);
rect(bubblex[i]+150-bgx,bubbley[i]+40,10,10);
}
bubblex[0]=bgx;
bubbley[0]=usery;
if(hacking){//下键无敌
fill(255,0,0);
text("作弊中",150,100);
}
if(gameOver==false || hacking){//计分方式
score=millis()/1000-wait;
if(score<20) text("分數: "+score+"分 你好菜",150,50);
else if(score<40) text("分數: "+score+"分 還不錯",150,50);
else if(score>=40) text("分數: "+score+"分 不可思議",150,50);
}
else if(gameOver && hacking==false){//死亡及结束画面
gameover.play();
background(255);
image(img2,0,0,600,350);
fill(255,0,0);
if(score<20) text("評價:你好菜",220,50);
else if(score<40) text("評價:還不錯",220,50);
else if(score>=40) text("評價:不可思議",220,50);
text("最終得分: "+score+"分",200,350);
}
}
}
boolean jumping=false;
boolean hacking=false;
void keyPressed(){//下键开启无敌
if(keyCode==DOWN){
if(hacking==false){
hacking=true;
}
}
if(keyCode==UP){//上键跳跃
jump.rewind();
jump.play();//跳跃音效
if(jumping==false){
jumping=true;
vy=-10;
}
}
}
boolean collision(){//前几周做的碰撞侦测
boolean b1=insideTriangle(150,usery);
boolean b2=insideTriangle(200,usery);
boolean b3=insideTriangle(200,usery+50);
boolean b4=insideTriangle(150,usery+50);
if(b1 || b2 || b3 || b4) return true;
else return false;
}
boolean insideTriangle(float x,float y){
float c1=cross(x,y,badx[now]-bgx,310,badx[now]-25-bgx,350);
float c2=cross(x,y,badx[now]-25-bgx,350,badx[now]+25-bgx,350);
float c3=cross(x,y,badx[now]+25-bgx,350,badx[now]-bgx,310);
if(c1>=0 && c2>=0 && c3>=0) return true;
else return false;
}
boolean collision2(){
boolean t1=insideTriangle2(150,usery);
boolean t2=insideTriangle2(200,usery);
boolean t3=insideTriangle2(200,usery+50);
boolean t4=insideTriangle2(150,usery+50);
if(t1 || t2 || t3 || t4) return true;
else return false;
}
boolean insideTriangle2(float x,float y){
float tc1=cross(x,y,trix[now2]+25-bgx,triy[now2]+40,trix[now2]-bgx,triy[now2]);
float tc2=cross(x,y,trix[now2]-bgx,triy[now2],trix[now2]+50-bgx,triy[now2]);
float tc3=cross(x,y,trix[now2]+50-bgx,triy[now2],trix[now2]+25-bgx,triy[now2]+40);
if(tc1<=0 && tc2<=0 && tc3<=0) return true;
else return false;
}
float cross(float xp,float yp,float x0,float y0,float x1,float y1){
return (xp-x0)*(y1-y0)-(yp-y0)*(x1-x0);
}
4.游戏说明
其他组员意见:
聆聽輕快的音樂再搭配上緊張刺激的跑酷遊戲!
Geometry Dash是我很喜歡玩的遊戲
每次死掉重來都令人懊惱但又激發了玩家不服輸的性格
雖然我們的重製沒能做出像原作般與音樂的完美契合
但緊張刺激的跑酷部分還是有還原到
也搭配上原作的首關音樂
希望可以讓更多人認識這款遊戲
游戏操作:
上鍵跳跃
下鍵作弊模式(不死)
每20分換背景與更新評價 40分封頂
隨著遊戲進行速度會越來越快
遊戲影片:https://youtu.be/OqANg5hwqAw
前面是正常遊玩 後半部作弊模式看40分以上
用时半个月,每周做一点,前几周做大致的框架和基本的程式码,最后一周做细节的修改,总共用时大约1-2天。
沒有留言:
張貼留言