融入动画技术的交互应用
融入動畫技術的交互應用
前言
之前使用過p5.js做一些簡單的編程,實現了一些簡單的交互,比如畫動態的風車、制做畫圖工具等;這次老師又提出了新的要求,讓我們結合《代碼本色》至少三個章節的技術來實現融入動畫技術的交互應用。課上學過一些力、向量什么的知識,再結合《代碼本色》上的粒子系統,我初步決定開發一款游戲,靈感來自以前老手機上玩的直升機小游戲,直升機會受到重力的作用,玩家需要操控直升機上下移動躲避前方的障礙物,獲得金幣,最后看最終的路程和積分。
初步嘗試
就像所有游戲開發一樣,首先需要準備游戲的基本資源,比如圖像、背景音樂等,不幸的是我記不起來那個直升機小游戲的名字了,就在我打算放棄的時候,我找到了一款比較相近的游戲——彩虹貓。彩虹貓不僅BGM十分洗腦,游戲模式也和我的預期十分相像,我也幸運的從偉大網友的分享資源里找到了游戲開發的圖片和音樂等資源,于是第一個難題算是解決了。
ps:Nyan Cat真的很洗腦,我之前聽過好幾遍都不知道它居然出自“彩虹貓”。
接下來總算可以正式開始編程了。首先我們需要創建一個main.js來設置p5.js中必要的三個函數:preload()、setup()和draw();代碼如下:
// main.jslet cat, stars; let resources = {catImg: [],starImg: [],rbImg: [] }function preload() {resources.rbImg[0] = loadImage("asset/rb.png");for (let i = 0; i < 12; i++)resources.catImg[i] = loadImage("asset/cat/cat" + i + ".png");for (let i = 0; i < 6; i++)resources.starImg[i] = loadImage("asset/star/star" + i + ".png"); }function setup() {createCanvas(window.innerWidth, window.innerHeight);frameRate(30); }function draw() {background(9, 37, 77);//image(resources.rbImg[0]); }文件里彩虹貓的貓圖片一共有12張,彩虹是一張,星星是6張,大致思路就是命名一下游戲過程中的兩個主要對象彩虹貓(因為貓和彩虹基本都是一起用到,所以就用一個對象了)和背景的星星,然后preload()預加載資源文件,setup()創建畫布并設置幀率,draw()暫時只設置背景顏色,如果順利的話對應的html文件打開來應該是藍色的背景。之后resources結構體里的內容還會不斷擴充,這里我打算先實現基本功能所以暫時不添加其它內容。
之后就要寫粒子系統了,我們創建一個Particle.js文件,代碼如下:
// Particle.jsclass Particle {constructor(image) {this.image = image;this.totalFrames = image.length;this.index = Math.round(random(0, this.totalFrames));this.position = null;this.speed = null;}birth(pos) {this.position = pos;}update() {this.position[0] -= this.speed;}isDead() {return this.position[0] < 0;}show() {this.index += (frameCount % 3 === 0);this.index %= this.totalFrames;imageMode(CENTER);image(this.image[this.index], this.position[0], this.position[1]);} }class ParticleSystem {constructor(image) {this.image = image;this.Particle = Particle; // constructor of particle classthis.list = [];this.rate = null; // emission rate}run() {this.emit();this.update();this.remove();this.show();}emit() {if (Math.random() < (this.rate / frameRate())) {let particle = new this.Particle(this.image);particle.birth([width, random(0, height)]);this.list.push(particle);}}update() {this.list.forEach(p => p.update());}remove() {this.list.forEach( (p, i, arr) => {if (p.isDead()) arr.splice(i, 1);});console.log(this.list.length);/*for (let i in this.list)if (this.list[i].isDead()) this.list.splice(i, 1); */}show() {this.list.forEach(p => p.show());} }class Star extends Particle {constructor(image) {super(image);this.speed = 24;} }class StarSystem extends ParticleSystem {constructor(image) {super(image);this.Particle = Star;this.rate = 9;} }class Rainbow extends Particle {constructor(image) {super(image);this.speed = 8;} }class RainbowSystem extends ParticleSystem {constructor(image) {super(image);this.Particle = Rainbow;}emit(pos) {let particle = new this.Particle(this.image);particle.birth(pos);this.list.push(particle);} }首先定義一個結構體代表每個粒子,每個粒子應該都具備誕生、位置變化、顯示以及死亡的功能,然后粒子系統就是讓每個粒子依次經歷這四個過程,自動隨即發射新的粒子,并檢查太‘老’的粒子把它從隊列中剔除出去。然后星星和彩虹都是繼承粒子和粒子系統的結構體,這里注意一個細節,彩虹移動的速度我設置為8是因為彩虹圖片的寬度只有9,速度大于9的話貓身后的彩虹就不連貫了;還有彩虹一直在貓身后所以我們要人為的給彩虹設置初始位置,所以要修改emit()函數。
之后就是我們的彩虹貓了,我們還需要控制貓的移動,新建一個NyanCat.js,代碼如下:
// NyanCat.jsclass NyanCat {constructor(catImg, rbImg) {this.position = [width * 0.38, height * 0.5];this.image = catImg;this.rainbow = new RainbowSystem(rbImg);this.speed = 30;this.emission = 4;}run() {this.emitRainbow();this.showCat();}emitRainbow() {for (let i = 0; i < this.emission; i++) {this.control();this.rainbow.emit([this.position[0], this.position[1] + this.oscillate(4, 0.5)]);this.rainbow.update();this.rainbow.remove();}this.rainbow.show();}oscillate(amplitude, omega) {return Math.round(amplitude * Math.sin(frameCount * omega));}control() {keyEvent(['W', 'w', UP_ARROW, ENTER], () => { this.position[1] -= this.speed / this.emission });keyEvent(['S', 's', DOWN_ARROW, SHIFT], () => { this.position[1] += this.speed / this.emission });/* if (keyIsPressed) {if (key == 'W' || key == 'w') this.position[1] -= this.speed / this.emission;if (key == 'S' || key == 's') this.position[1] += this.speed / this.emission;} */this.checkEdges();}checkEdges() {if (this.position[1] > height) this.position[1] = height;if (this.position[1] < 0) this.position[1] = 0;}showCat() {let index = Math.floor(frameCount / 2) % this.image.length;imageMode(CENTER);image(this.image[index], this.position[0], this.position[1]);} }function keyEvent(input, func) {if (keyIsPressed && input.some( value => (value === keyCode || value === key) ))func(); }這里提一下,emitRainbow()函數中我把emit()、update()、remove()三個函數用for循環做了4遍,主要是為了讓彩虹的上下擺動看上去更加流暢,不信的話你可以把for循環去掉對比下試試看。
最后不要忘記在我們的main.js中初始化一下粒子系統和彩虹貓的對象。
// main.jslet cat, stars; let resources = {catImg: [],starImg: [],rbImg: [] }function preload() {resources.rbImg[0] = loadImage("asset/rb.png");for (let i = 0; i < 12; i++)resources.catImg[i] = loadImage("asset/cat/cat" + i + ".png");for (let i = 0; i < 6; i++)resources.starImg[i] = loadImage("asset/star/star" + i + ".png"); }function setup() {createCanvas(window.innerWidth, window.innerHeight);frameRate(30);stars = new StarSystem(resources.starImg);cat = new NyanCat(resources.catImg, resources.rbImg); }function draw() {background(9, 37, 77);stars.run();cat.run(); }這樣一來“彩虹貓”游戲就初步完成了,我們已經可以控制彩虹貓上下移動并且背景中有一閃一閃的星星。html文件的打開推薦使用火狐瀏覽器,打開來效果應該是這樣的:
進一步完善
現在“彩虹貓”游戲還欠缺哪些東西呢?我這里整理下:背景音樂、障礙物系統、重力系統、硬幣積分系統、游戲開始以及結束的提示文字等。這里就不再一一介紹完善的過程,直接放上代碼的百度云鏈接,需要的朋友可以自行下載。這里順便放上兩張游戲截圖看下最終的效果。
鏈接:https://pan.baidu.com/s/1qU41MPZwNmSan27t7PrYIw 提取碼:ecwp
總結
彩虹貓的游戲開發至此算告一段落了,感興趣的朋友可以在此基礎上進一步改進完善;這篇博文的主要目的是展示粒子系統如何編寫和使用,相信掌握粒子系統之后會對大家以后p5.js或者processing的編程會有很大幫助。
總結
以上是生活随笔為你收集整理的融入动画技术的交互应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 细胞分类 识别 系统
- 下一篇: 新疆计算机信息管理专升本可以报哪些专业,