這是本人第一次寫博客,是寫給自己看的吧,標誌着我下定決心開始走程序媛這條路了。
而且這也是我第一次用Processing寫小遊戲,算是紀念了。
首先帖一張運行初始界面圖:
我們可以看到最下面那個警察是玩家,上面有4只殭屍,一隻狙擊手還有一個殺手。
醫生是橫着走而且超出界面後不會返回。
然後我們要對每個NPC定義它特有的屬性,它是橫着走還是豎着走,速度怎麼樣還有它和玩家相碰之後的結果。
下面是殭屍、狙擊以及殺手的特性:
碰到殭屍後遊戲不會結束,但是要找醫生才能解除屏幕上的提示,當醫生不在後如果再碰到殭屍遊戲立刻結束。
PImage img=new PImage();
float speed; //將速度定義爲全局變量
Enemy enemy1_1,enemy1_2,enemy1_3,enemy1_4; //4只殭屍
class Enemy
{
float img_x,img_y;
Enemy(float x, float y,float sd)
{
img_x=x;
img_y=y;
speed=sd;
}
void movel1()
{ img_x+=speed;
if(img_x>width-80) //殭屍是來回走的
{
img_x=40;
}
}
void movel2()
{ img_x-=speed;
if(img_x<40)
{
img_x=width-80;
}
}
boolean contact() //檢測是否和殭屍碰到
{
float Offset = dist(img_x,img_y,X,Y); //距離
boolean bContact =false ;
if(Offset<=55) //如果兩個距離小於55說明相碰返回true
{
bContact=true;
}
return bContact;
}
void display()
{
image(img,img_x,img_y);
if(life==1)
{
color c=color(255,204,0);
pushStyle();
fill(c);
textFont(font,25);
text("You have to find the doctor!",width/2-140,height/2);
//生命值爲1說明和殭屍相碰了
popStyle();
}
}
}
PImage img6=new PImage(); //狙擊
Juji juji;
class Juji
{ float img6_x,img6_y;
Juji(float x, float y,float sd)
{
img6_x=x;
img6_y=y;
speed=sd;
}
void display()
{
image(img6,img6_x,img6_y);
}
void movel3()
{
img6_y+=speed;
if(img6_y>450)
{
img6_y=150;
}
}
boolean contact() //檢測是否和狙擊碰到
{
float Offset = dist(img6_x,img6_y,X,Y); //distance
boolean bContact =false ;
if(Offset<=55)
{
bContact=true;
}
return bContact;
}
}
PImage img3=new PImage(); //殺手
Shashou shashou;
float speed1=0.1;
class Shashou
{
float angle=0.0;
float offset=270;
float scalar=30;
float sha_x,sha_y;
Shashou()
{
}
void move() //這裏是定義了殺手以怎樣的方式移動,大概是畫圈的形式
{
sha_x= offset+cos(angle)*scalar;
sha_y= (offset+sin(angle)*scalar-180)*1.5;
angle+=speed1;
}
void display()
{
image(img3,sha_x,sha_y);
}
}
然後下面是醫生的特性
/**
本頁是有關醫生的函數及定義
**/
Doctor doctor;
PImage img5=new PImage(); //醫生
boolean disapper=false;
int doctor_speed=5;
class Doctor
{
float img5_x,img5_y;
Doctor(float x, float y)
{
img5_x=x;
img5_y=y;
}
void movel()
{
img5_x+=doctor_speed;
if(img5_x>width)
{
disapper=true;
}
}
void display()
{
image(img5,img5_x,img5_y);
}
boolean contact() //檢測是否和醫生碰到
{
float Offset = dist(img5_x,img5_y,X,Y); //distance
boolean bContact =false ;
if(Offset<=35)
{
bContact=true;
}
return bContact;
}
}
基本和前面敵人的定義方式差不多所以就不多說了。
還有最重要的玩家:
PImage img2=new PImage(); //警察
int X;
int Y;
int life;
boolean arrive=false;
class Player{
Player(int XX,int YY) {
X=XX;
Y=YY;
life=2;
}
void move()
{
if(mousePressed&&life!=3)
{
X+=(mouseX-X)/2.000;
Y+=(mouseY-Y)/2.000;
}
if(mousePressed&&mouseButton==RIGHT)
{
X=mouseX-10;
Y=mouseY-5;
}
if(life==0)
{
X=width/2-20;
Y=height-70;
speed=0;
speed1=0;
color c=color(255,204,0);
fill(c);
textFont(font,25);
text("Game Over,you failed!",width/2-120,height/2);
drawbutton(width/2-30,height/2+20);
player.close();
}
if((X>width/2-50)&&(X<width/2+30)&&(Y>120)&&(Y<175))
{
arrive=true; //判斷是否到達目的地
}
else
{
arrive=false;
}
}
void drawbutton(int xx,int yy) //在遊戲結束時弄一個類似按鈕的東西,點擊一下退出遊戲
{
noFill();
rect(xx,yy,40,20);
stroke(204, 102, 0);
textSize(15);
text("EXIT",xx+8,yy+14);
if(mousePressed&&(mouseX>xx)
&&(mouseX<xx+40)&&(mouseY>yy)&&(mouseY<yy+20))
{
exit();
}
}
void display()
{
image(img2,X,Y);
}
void update()
{
}
}
編到中後期的時候纔想說把字體換一下,用默認的太醜了,而processing的字體是要下載的,在這裏順便說一下換字體的方法:
點擊 【工具】->【創建字體】,然後選一個自己喜歡的字體,複製好它的名字如AxureHandwriting-Italic-38.vlw,然後按確認。
調用代碼可以這樣寫:
PFont font;
font = loadFont("AxureHandwriting-Italic-38.vlw");
textFont(font,25);
text("hello,girl!",width/2-120,height/2);
大家還可以像我遊戲中那樣定義一個顏色什麼的。
最後是主界面的繪製以及那些寫好的函數的調用:
/**
本頁是調用函數
其中包含初始界面、背景音樂以及玩家敵人的調用
**/
import ddf.minim.*;
Minim minim;
AudioPlayer player;
int diameter;
Time timer;
PFont font;
int situation=0;
PImage img4=new PImage(); //背景1
int rectX,rectY; //按鈕的長寬
int rectSize=90;
color rectColor;
color currentColor;
boolean rectOver=false;
Player protagonist;
void setup()
{
size(640,680);
timer=new Time(40);
font = loadFont("AxureHandwriting-Italic-38.vlw");
img = loadImage("殭屍1.png");
img2=loadImage("警察.png");
img3=loadImage("殺手.png");
img4=loadImage("背景1.jpg");
img5=loadImage("醫生.png");
img6=loadImage("狙擊.png");
minim=new Minim(this);
player=minim.loadFile("background.mp3",560); //音頻要事先準備好
player.play();
protagonist = new Player(width/2-25,height-70);//生成主角
enemy1_1=new Enemy(3,120,22); //生成殭屍
enemy1_2=new Enemy(width-200,230,20);
enemy1_3=new Enemy(width/2-30,340,32);
enemy1_4=new Enemy(width/2-10,450,25);
doctor=new Doctor(0,height-130);
juji=new Juji(width/2-20,170,10);
shashou=new Shashou();
}
void drawGameOver1()
{
color c=color(255,0,0);
fill(c);
textFont(font,25);
text("Congratulations,You win!",width/2-120,height/2);
}
void drawGameOver3()
{
color c=color(255,204,0);
fill(c);
textFont(font,25);
text("Time is up,you failed!",width/2-120,height/2);
}
void draw()
{
frameRate(10);
image(img4,0,0);
if(situation==0)
{
pushStyle();
textSize(20);
text(millis()/1000,10,height-10);
popStyle();
}
protagonist.display();
protagonist.move();
enemy1_1.display();
enemy1_1.movel1();
enemy1_2.display();
enemy1_2.movel2();
enemy1_3.display();
enemy1_3.movel1();
enemy1_4.display();
enemy1_4.movel2();
doctor.display();
doctor.movel();
juji.display();
juji.movel3();
shashou.display();
shashou.move();
if(enemy1_1.contact()||enemy1_2.contact()
||enemy1_3.contact()||enemy1_4.contact()) //如果遇到的是殭屍,
{
life=1; //碰到殭屍後生命值爲1
speed=0;
if(disapper) //如果碰到了殭屍且醫生不在了
{
life=0;
situation=1;
}
}
if(juji.contact())
{
life=0;
doctor_speed=0;
situation=1;
}
if(doctor.contact())
{
life=2;
speed=22;
}
if(timer.isFinished())
{
if(arrive&&life!=1) //如果沒到時間且到達終點且生命值不爲1
{ //life==1表示遇到了喪屍,即使到了目的地也不能算贏
situation=1;
life=3; //如果贏了將生命置爲3,這樣就不能拖動玩家了
speed=0;
speed1=0;
doctor_speed=0;
player.close();
drawGameOver1();
protagonist.drawbutton(width/2-30,height/2+20);
}
}
else if(!timer.isFinished()&&life!=0)
{ situation=1;
life=3;
speed=0;
speed1=0;
doctor_speed=0;
player.close();
drawGameOver3();
protagonist.drawbutton(width/2-30,height/2+20);
}
}
細緻的你們應該會發現我還弄了一個計時的,我定義的遊戲時間是40s,如果到時間了你沒能到達目的地就算輸;還有如果碰到了殭屍但是你沒能找到醫生救你就算到了目的地也不會顯示贏;還有當遊戲結束了所有的都不能動,時間也不會顯示,你也不能拖動玩家了,爲了解決這些問題我就設了life,situation,speed,arrive等全局變量。
所以之間的邏輯還是有點複雜的,我也是弄了好久才理清;
下面是Time 這個類:
class Time{
int totaltime;
Time(int temptotaltime) //將40s傳遞給totaltime
{
totaltime=temptotaltime;
}
boolean isFinished()
{
int passedtime=millis()/1000;
if(passedtime>totaltime)
{
return false; //如果過去的時間大於40s返回false
}
else
{
return true;
}
}
}
時間到了之後會提示,並且遊戲結束:
大家可以看到醫生已經看不見,移出界了。
在顯示時間的時候一開始我也是懵逼的,因爲我想着是用second(),但是時間總是顯示不對,而且就算把遊戲叉掉再打開運行,它的時間也不是從零開始算而是接着前面的時間。
後來我才發現要用millis()。
整個遊戲有4個類外加一個調用的:
由於接觸processing不多,一開始連怎樣引用音頻、改字體、用中文寫註釋、添加類等等這些很簡單的東西都不會,但是自己一點一點摸索還是弄出了這個遊戲。而且代碼不夠精煉。
不過還是想吐槽一下processing,它不像vs,eclipse等編輯器那樣給你提示哪個函數有問題,應該怎樣寫等等,比如我寫textSize時寫成了textsize,它也只會顯示紅線而不會說改成什麼,我覺得這點很不好。而且它的有些錯誤提示本身就是錯的。
最後還是感謝一下“愛上processing”這篇文章。
如果有人能看到這篇博客,也希望它能在你使用processing時對你有點幫助~