根据老师的要求,创作一幅介绍自己的作品,可以是具象化地描绘形象,也可以是任何形式表现自己的兴趣、追求、特色、经历等。
由于最近比较喜欢一款FPS游戏,就做了里面的一把枪的模型。另外实现了一些动态效果和交互效果。
p5.js,编程环境:p5.js在线编程
将整个模型分为四个模块:消音器、枪管、连接座、弹夹。
就是简单的图形堆叠,仔细观察原图,使用ellipse(),rect(),triangle()等函数实现功能。具体的看我下面的
//绘制消音管的函数
function silenceTube(x,y){
fill(30)
rect(x+60,y+30,180,30)
ellipse(x+240,y+45,10,30)
ellipse(x+160,y+45,5,32)
ellipse(x+80,y+45,5,32)
rect(x+50,y+35,10,20)
}
//绘制枪管的函数
function barrel(x,y){
fill(80)
rect(x+220,y+25,20,10,2)
rect(x+245,y+40,5,10)
rect(x+65,y+33,180,28)
triangle(x+65,y+28,x+60,y+61,x+65,y+61)
rect(x+65,y+31,20,2)
triangle(x+65,y+28,x+65,y+31,x+70,y+31)
triangle(x+64,y+41,x+62,y+48,x+56,y+42)
arc(x+60,y+42,8,8,PI,0)
fill(200)
rect(x+140,y+33,30,20)
}
//绘制连接座的函数
function connection(x,y){
fill(80)
rect(x+105,y+66,139,12)
triangle(x+118,y+91,x+114,y+104,x+133,y+104)
rect(x+128,y+100,30,4)
triangle(x+164,y+79,x+158,y+104,x+164,y+104)
triangle(x+164,y+79,x+164,y+104,x+170,y+79)
fill(0)
rect(x+60,y+61,185,5)
rect(x+60,y+66,45,12)
triangle(x+60,y+61,x+56,y+78,x+60,y+78)
triangle(x+57,y+78,x+71,y+83,x+71,y+78)
triangle(x+71,y+78,x+60,y+163,x+71,y+163)
rect(x+71,y+78,40,85)
triangle(x+111,y+163,x+111,y+78,x+122,y+78)
triangle(x+122,y+78,x+135,y+78,x+118,y+91)
noFill()
arc(x+150,y+85,12,15,-3/2*PI,-1/2*PI)
arc(x+151,y+85,12,15,-3/2*PI,-1/2*PI)
arc(x+149,y+85,12,15,-3/2*PI,-1/2*PI)
}
//绘制弹夹的函数
function pistolClip(x,y){
fill(0)
triangle(x+86,y+90,x+86,y+158,x+71,y+158)
rect(x+86,y+88,20,70)
triangle(x+106,y+88,x+106,y+156,x+121,y+88)
rect(x+71,y+158,40,5)
triangle(x+111,y+158,x+111,y+163,x+116,y+163)
}
模型建好之后,后面是一些动态效果和交互效果的实现。
动态效果包括:背景的变色和子弹的向前发射。
交互效果包括:点击鼠标左键将手枪拆开 和 按下键盘空格键 手枪发射子弹。
- 背景变色:
使用三个变量,r , g , b ,用来作为颜色的值,然后在draw()函数中改变这三个值,达到改变背景颜色的效果。
background(r,g,b);
r +=2;
g +=3;
b +=1;
if(r>255)
r=0;
if(g>255)
g=0;
if(b>255)
b=0;
- 子弹向前发射:
设置子弹的相对坐标(bulletx,bullety),通过在函数中增加bulletx的值,达到子弹向前发射的效果,其中子弹的颜色刚好与背景颜色相对。
bulletx += 30
if(bulletx >= 800)
bulletx = 490
// 下面是子弹构成的代码
fill(255-r,255-g,255-b)
ellipse(bulletx,bullety,2,6)
rect(bulletx,bullety-3,10,6)
triangle(bulletx+10,bullety-3,bulletx+10,bullety+3,bulletx+15,bullety)
- 点击鼠标左键将手枪拆开:
使用了p5.js自带的变量mouseIsPressed以及mouseButton,这两个变量都是关于p5.js的鼠标交互事件,具体可以看:p5.js入门教程(4) 鼠标交互
按下鼠标左键之后,手枪拆分成之前说的四个模块,分别置于鼠标当前位置的上下左右,可移动。
// 鼠标事件
if(mouseIsPressed){
// 点击鼠标左键
if(mouseButton == LEFT){
// 绕鼠标点转,半径为100
silenceTube(mouseX-150,mouseY-200)
barrel(mouseX+50,mouseY-50)
connection(mouseX-300,mouseY-100)
pistolClip(mouseX-100,mouseY+50)
}
}
- 按下键盘空格键手枪发射子弹:
使用了p5.js自带的变量keyIsPressed和key,是关于p5.js的键盘交互事件,具体可以看:p5.js入门教程(5) 键盘交互
按下键盘空格键,当前手枪换位置,然后枪口发射子弹,子弹向前发射,参考前面的介绍。
// 键盘事件
if(keyIsPressed){
// 按下键盘空格键
if(key == ' '){
bulletx += 30
if(bulletx >= 800)
bulletx = 490
silenceTube(250,250)
barrel(50,250)
connection(50,250)
pistolClip(50,250)
// 下面是子弹构成的代码
fill(255-r,255-g,255-b)
ellipse(bulletx,bullety,2,6)
rect(bulletx,bullety-3,10,6)
triangle(bulletx+10,bullety-3,bulletx+10,bullety+3,bulletx+15,bullety)
}
}
再后面就是关于最后一个元素,图中的文字。
图中的文字分为两个部分,一个是USP消音版,这是这把手枪在游戏中的名字;一个是by 顾清宇,顾清宇是我的艺名,所以我用了顾清宇,毕竟是创作嘛,哈哈!
另外,值得一提的是,字体的颜色总是和背景色相反,这样可以看的清楚一点。
textSize(32);
fill(255-r,255-g,255-b)
text('USP消音版', 280, 60);
text('____________',275,75)
text('by 顾清宇', 600, 550);
p5.js,编程环境:p5.js在线编程
//创意自画像的代码
function setup() {
createCanvas(800, 600);
}
var r=50,g=50,b=50; // 背景颜色的坐标
var bulletx=490, bullety=295; // 子弹的坐标
function draw() {
background(r,g,b);
r +=2;
g +=3;
b +=1;
if(r>255)
r=0;
if(g>255)
g=0;
if(b>255)
b=0;
textSize(32);
fill(255-r,255-g,255-b)
text('USP消音版', 280, 60);
text('____________',275,75)
text('by 顾清宇', 600, 550);
// 没有鼠标和键盘事件
if(!mouseIsPressed && !keyIsPressed)
{
silenceTube(300,100)
barrel(100,100)
connection(100,100)
pistolClip(100,100)
}
// 鼠标事件
if(mouseIsPressed){
// 点击鼠标左键
if(mouseButton == LEFT){
// 绕鼠标点转,半径为100
silenceTube(mouseX-150,mouseY-200)
barrel(mouseX+50,mouseY-50)
connection(mouseX-300,mouseY-100)
pistolClip(mouseX-100,mouseY+50)
}
}
// 键盘事件
if(keyIsPressed){
// 按下键盘空格键
if(key == ' '){
bulletx += 30
if(bulletx >= 800)
bulletx = 490
silenceTube(250,250)
barrel(50,250)
connection(50,250)
pistolClip(50,250)
// 下面是子弹构成的代码
fill(255-r,255-g,255-b)
ellipse(bulletx,bullety,2,6)
rect(bulletx,bullety-3,10,6)
triangle(bulletx+10,bullety-3,bulletx+10,bullety+3,bulletx+15,bullety)
}
}
}
//绘制消音管的函数
function silenceTube(x,y){
fill(30)
rect(x+60,y+30,180,30)
ellipse(x+240,y+45,10,30)
ellipse(x+160,y+45,5,32)
ellipse(x+80,y+45,5,32)
rect(x+50,y+35,10,20)
}
//绘制枪管的函数
function barrel(x,y){
fill(80)
rect(x+220,y+25,20,10,2)
rect(x+245,y+40,5,10)
rect(x+65,y+33,180,28)
triangle(x+65,y+28,x+60,y+61,x+65,y+61)
rect(x+65,y+31,20,2)
triangle(x+65,y+28,x+65,y+31,x+70,y+31)
triangle(x+64,y+41,x+62,y+48,x+56,y+42)
arc(x+60,y+42,8,8,PI,0)
fill(200)
rect(x+140,y+33,30,20)
}
//绘制连接座的函数
function connection(x,y){
fill(80)
rect(x+105,y+66,139,12)
triangle(x+118,y+91,x+114,y+104,x+133,y+104)
rect(x+128,y+100,30,4)
triangle(x+164,y+79,x+158,y+104,x+164,y+104)
triangle(x+164,y+79,x+164,y+104,x+170,y+79)
fill(0)
rect(x+60,y+61,185,5)
rect(x+60,y+66,45,12)
triangle(x+60,y+61,x+56,y+78,x+60,y+78)
triangle(x+57,y+78,x+71,y+83,x+71,y+78)
triangle(x+71,y+78,x+60,y+163,x+71,y+163)
rect(x+71,y+78,40,85)
triangle(x+111,y+163,x+111,y+78,x+122,y+78)
triangle(x+122,y+78,x+135,y+78,x+118,y+91)
noFill()
arc(x+150,y+85,12,15,-3/2*PI,-1/2*PI)
arc(x+151,y+85,12,15,-3/2*PI,-1/2*PI)
arc(x+149,y+85,12,15,-3/2*PI,-1/2*PI)
}
//绘制弹夹的函数
function pistolClip(x,y){
fill(0)
triangle(x+86,y+90,x+86,y+158,x+71,y+158)
rect(x+86,y+88,20,70)
triangle(x+106,y+88,x+106,y+156,x+121,y+88)
rect(x+71,y+158,40,5)
triangle(x+111,y+158,x+111,y+163,x+116,y+163)
}