pixi(入门)
Pixi教程
目录:
介绍
安装
安装 Pixi
创建舞台(stage)和画布(renderer)
Pixi 精灵
把图像加载进纹理缓存
显示精灵(sprite)
使用普通的javaScript Img对象或canvas创建一个精灵
给已经加载的文件设定一个名字
监视加载进程
一些关于Pixi的加载器的其他知识
使用别名
一些关于加载的其他知识
定位精灵
大小和比例
角度
从精灵图(雪碧图)中获取精灵
使用一个纹理贴图集
加载纹理贴图集
从一个纹理贴图集创建精灵
移动精灵
使用速度属性
游戏状态
键盘响应
将精灵分组
局部位置和全局位置
使用 ParticleContainer 分组精灵
用 Pixi 绘制几何图形
矩形
圆形
椭圆
圆角矩形
线
多边形
显示文本
碰撞检测
一个 hitTestRectangle 函数
实例学习: 宝物猎人
限制移动范围
创建游戏场景
创建地牢,门,猎人和宝箱
创建泡泡怪(这个怪物好萌)
创建血条
创建提示文本
用 setup 函数初始化游戏
开始游戏
移动猎人
移动泡泡怪们
碰撞检测
处理到达出口和结束游戏
一些关于精灵的其他知识
展望未来
i. Hexi
ii. BabylonJS
支持这个工程
介绍
安装
安装 Pixi
<script src="pixi.min.js"></script>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
</head>
<script src="pixi/pixi.min.js"></script>
<body>
<script type="text/javascript">
let type = "WebGL"
if(!PIXI.utils.isWebGLSupported()){
type = "canvas"
}
PIXI.utils.sayHello(type)
</script>
</body>
</html>PixiJS 4.4.5 - * canvas * http://HdhCmsTestpixijs测试数据/ ???
创建Pixi应用和 舞台
//Create a Pixi Application
let app = new PIXI.Application({width: 256, height: 256});
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);let app = new PIXI.Application({
width: 256, // default: 800
height: 256, // default: 600
antialias: true, // default: false
transparent: false, // default: false
resolution: 1 // default: 1
}
);forceCanvas: true,
app.renderer.backgroundColor = 0x061639;
app.renderer.autoResize = true; app.renderer.resize(512, 512);
app.renderer.view.style.position = "absolute";app.renderer.view.style.display = "block";app.renderer.autoResize = true;app.renderer.resize(window.innerWidth, window.innerHeight);
<style>* {padding: 0; margin: 0}</style>Pixi 精灵
app.stage
用一个单图像文件创建。
用一个 雪碧图 来创建。雪碧图是一个放入了你游戏所需的所有图像的大图。
从一个纹理贴图集中创建。(纹理贴图集就是用JSON定义了图像大小和位置的雪碧图)
将图片加载到纹理缓存中
PIXI.utils.TextureCache["images/cat.png"];
let texture = PIXI.utils.TextureCache["images/anySpriteImage.png"]; let sprite = new PIXI.Sprite(texture);
PIXI.loader
.add("images/anyImage.png")
.load(setup);
function setup() {
//This code will run when the loader has finished loading the image
}let sprite = new PIXI.Sprite( PIXI.loader.resources["images/anyImage.png"].texture );
PIXI.loader
.add("images/anyImage.png")
.load(setup);
function setup() {
let sprite = new PIXI.Sprite(
PIXI.loader.resources["images/anyImage.png"].texture
);
}PIXI.loader
.add("images/imageOne.png")
.add("images/imageTwo.png")
.add("images/imageThree.png")
.load(setup);PIXI.loader .add([ "images/imageOne.png", "images/imageTwo.png", "images/imageThree.png" ]) .load(setup);
显示精灵
app.stage.addChild(cat);
//Create a Pixi Application
let app = new PIXI.Application({
width: 256,
height: 256,
antialias: true,
transparent: false,
resolution: 1
}
);
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);
//load an image and run the `setup` function when it's done
PIXI.loader
.add("images/cat.png")
.load(setup);
//This `setup` function will run when the image has loaded
function setup() {
//Create the cat sprite
let cat = new PIXI.Sprite(PIXI.loader.resources["images/cat.png"].texture);
//Add the cat to the stage
app.stage.addChild(cat);
}app.stage.removeChild(anySprite)
anySprite.visible = false;
使用别名
let TextureCache = PIXI.utils.TextureCache
let texture = TextureCache["images/cat.png"];
//Aliases
let Application = PIXI.Application,
loader = PIXI.loader,
resources = PIXI.loader.resources,
Sprite = PIXI.Sprite;
//Create a Pixi Application
let app = new Application({
width: 256,
height: 256,
antialias: true,
transparent: false,
resolution: 1
}
);
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);
//load an image and run the `setup` function when it's done
loader
.add("images/cat.png")
.load(setup);
//This `setup` function will run when the image has loaded
function setup() {
//Create the cat sprite
let cat = new Sprite(resources["images/cat.png"].texture);
//Add the cat to the stage
app.stage.addChild(cat);
}一些关于加载的其他知识
let base = new PIXI.BaseTexture(anyImageObject), texture = new PIXI.Texture(base), sprite = new PIXI.Sprite(texture);
let base = new PIXI.BaseTexture.fromCanvas(anyCanvasElement),
anySprite.texture = PIXI.utils.TextureCache["anyTexture.png"];
PIXI.loader
.add("catImage", "images/cat.png")
.load(setup);let cat = new PIXI.Sprite(PIXI.loader.resources.catImage.texture);
PIXI.loader.on("progress", loadProgressHandler);PIXI.loader
.add([
"images/one.png",
"images/two.png",
"images/three.png"
])
.on("progress", loadProgressHandler)
.load(setup);
function loadProgressHandler() {
console.log("loading");
}
function setup() {
console.log("setup");
}loading loading loading setup
function loadProgressHandler(loader, resource) { /*...*/ }PIXI.loader
.add([
"images/one.png",
"images/two.png",
"images/three.png"
])
.on("progress", loadProgressHandler)
.load(setup);
function loadProgressHandler(loader, resource) {
//Display the file `url` currently being loaded
console.log("loading: " + resource.url);
//Display the percentage of files currently loaded
console.log("progress: " + loader.progress + "%");
//If you gave your files names as the first argument
//of the `add` method, you can access them like this
//console.log("loading: " + resource.name);
}
function setup() {
console.log("All files loaded");
}loading: images/one.png progress: 33.333333333333336% loading: images/two.png progress: 66.66666666666667% loading: images/three.png progress: 100% All files loaded
add(name, url, optionObject, callbackFunction)
.add('key', 'http://...', function () {})
.add('http://...', function () {})
.add('http://...').add({
name: 'key2',
url: 'http://...'
}, function () {})
.add({
url: 'http://...'
}, function () {})
.add({
name: 'key3',
url: 'http://...'
onComplete: function () {}
})
.add({
url: 'https://...',
onComplete: function () {},
crossOrigin: true
}).add([
{name: 'key4', url: 'http://...', onComplete: function () {} },
{url: 'http://...', onComplete: function () {} },
'http://...'
]);精灵位置
cat.x = 96; cat.y = 96;
function setup() {
//Create the `cat` sprite
let cat = new Sprite(resources["images/cat.png"].texture);
//Change the sprite's position
cat.x = 96;
cat.y = 96;
//Add the cat to the stage so you can see it
app.stage.addChild(cat);
}sprite.position.set(x, y)
大小和比例
cat.width = 80; cat.height = 120;
function setup() {
//Create the `cat` sprite
let cat = new Sprite(resources["images/cat.png"].texture);
//Change the sprite's position
cat.x = 96;
cat.y = 96;
//Change the sprite's size
cat.width = 80;
cat.height = 120;
//Add the cat to the stage so you can see it
app.stage.addChild(cat);
}cat.scale.x = 0.5; cat.scale.y = 0.5;
cat.scale.x = 2; cat.scale.y = 2;
cat.scale.set(0.5, 0.5);
旋转
cat.rotation = 0.5;
cat.anchor.x = 0.5; cat.anchor.y = 0.5;
cat.anchor.set(x, y)
cat.pivot.set(32, 32)
从精灵图(雪碧图)中创建精灵【为了防止与精灵混淆,我在之后的译文中都将采用雪碧图这一译法】
loader
.add("images/tileset.png")
.load(setup);function setup() {
//Create the `tileset` sprite from the texture
let texture = TextureCache["images/tileset.png"];
//Create a rectangle object that defines the position and
//size of the sub-image you want to extract from the texture
//(`Rectangle` is an alias for `PIXI.Rectangle`)
let rectangle = new Rectangle(192, 128, 64, 64);
//Tell the texture to use that rectangular section
texture.frame = rectangle;
//Create the sprite from the texture
let rocket = new Sprite(texture);
//Position the rocket sprite on the canvas
rocket.x = 32;
rocket.y = 32;
//Add the rocket to the stage
app.stage.addChild(rocket);
//Render the stage
renderer.render(stage);
}let rectangle = new PIXI.Rectangle(x, y, width, height);
let rectangle = new Rectangle(192, 128, 64, 64); texture.frame = rectangle;
let rocket = new Sprite(texture);
使用一个纹理贴图集
"blob.png":
{
"frame": {"x":55,"y":2,"w":32,"h":24},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":32,"h":24},
"sourceSize": {"w":32,"h":24},
"pivot": {"x":0.5,"y":0.5}
},加载纹理贴图集
loader
.add("images/treasureHunter.json")
.load(setup);从已经加载的纹理贴图集中创建精灵
使用 TextureCache :
let texture = TextureCache["frameId.png"], sprite = new Sprite(texture);
如果你是使用的 loader 来加载纹理贴图集, 使用loader的 resources :
let sprite = new Sprite( resources["images/treasureHunter.json"].textures["frameId.png"] );
要创建一个精灵需要输入太多东西了! 所以我建议你给纹理贴图集的 textures 对象创建一个叫做 id 的别名,象是这样:
let id = PIXI.loader.resources["images/treasureHunter.json"].textures;
let sprite = new Sprite(id["frameId.png"]);
//Define variables that might be used in more
//than one function
let dungeon, explorer, treasure, id;
function setup() {
//There are 3 ways to make sprites from textures atlas frames
//1. Access the `TextureCache` directly
let dungeonTexture = TextureCache["dungeon.png"];
dungeon = new Sprite(dungeonTexture);
app.stage.addChild(dungeon);
//2. Access the texture using throuhg the loader's `resources`:
explorer = new Sprite(
resources["images/treasureHunter.json"].textures["explorer.png"]
);
explorer.x = 68;
//Center the explorer vertically
explorer.y = app.stage.height / 2 - explorer.height / 2;
app.stage.addChild(explorer);
//3. Create an optional alias called `id` for all the texture atlas
//frame id textures.
id = PIXI.loader.resources["images/treasureHunter.json"].textures;
//Make the treasure box using the alias
treasure = new Sprite(id["treasure.png"]);
app.stage.addChild(treasure);
//Position the treasure next to the right edge of the canvas
treasure.x = app.stage.width - treasure.width - 48;
treasure.y = app.stage.height / 2 - treasure.height / 2;
app.stage.addChild(treasure);
}explorer.y = app.stage.height / 2 - explorer.height / 2;
<!doctype html>
<meta charset="utf-8">
<title>Make a sprite from a texture atlas</title>
<body>
<script src="pixi/pixi.min.js"></script>
<script>
//Aliases
let Application = PIXI.Application,
Container = PIXI.Container,
loader = PIXI.loader,
resources = PIXI.loader.resources,
TextureCache = PIXI.utils.TextureCache,
Sprite = PIXI.Sprite,
Rectangle = PIXI.Rectangle;
//Create a Pixi Application
let app = new Application({
width: 512,
height: 512,
antialias: true,
transparent: false,
resolution: 1
}
);
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);
//load a JSON file and run the `setup` function when it's done
loader
.add("images/treasureHunter.json")
.load(setup);
//Define variables that might be used in more
//than one function
let dungeon, explorer, treasure, door, id;
function setup() {
//There are 3 ways to make sprites from textures atlas frames
//1. Access the `TextureCache` directly
let dungeonTexture = TextureCache["dungeon.png"];
dungeon = new Sprite(dungeonTexture);
app.stage.addChild(dungeon);
//2. Access the texture using throuhg the loader's `resources`:
explorer = new Sprite(
resources["images/treasureHunter.json"].textures["explorer.png"]
);
explorer.x = 68;
//Center the explorer vertically
explorer.y = app.stage.height / 2 - explorer.height / 2;
app.stage.addChild(explorer);
//3. Create an optional alias called `id` for all the texture atlas
//frame id textures.
id = PIXI.loader.resources["images/treasureHunter.json"].textures;
//Make the treasure box using the alias
treasure = new Sprite(id["treasure.png"]);
app.stage.addChild(treasure);
//Position the treasure next to the right edge of the canvas
treasure.x = app.stage.width - treasure.width - 48;
treasure.y = app.stage.height / 2 - treasure.height / 2;
app.stage.addChild(treasure);
//Make the exit door
door = new Sprite(id["door.png"]);
door.position.set(32, 0);
app.stage.addChild(door);
//Make the blobs
let numberOfBlobs = 6,
spacing = 48,
xOffset = 150;
//Make as many blobs as there are `numberOfBlobs`
for (let i = 0; i < numberOfBlobs; i++) {
//Make a blob
let blob = new Sprite(id["blob.png"]);
//Space each blob horizontally according to the `spacing` value.
//`xOffset` determines the point from the left of the screen
//at which the first blob should be added.
let x = spacing * i + xOffset;
//Give the blob a random y position
//(`randomInt` is a custom function - see below)
let y = randomInt(0, app.stage.height - blob.height);
//Set the blob's position
blob.x = x;
blob.y = y;
//Add the blob sprite to the stage
app.stage.addChild(blob);
}
}
//The `randomInt` helper function
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
</script>
</body>let x = spacing * i + xOffset; blob.x = x;
let y = randomInt(0, stage.height - blob.height); blob.y = y;
randomInt(lowestNumber, highestNumber)
let randomNumber = randomInt(1, 10);
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}移动精灵
function setup() {
//Start the game loop by adding the `gameLoop` function to
//Pixi's `ticker` and providing it with a `delta` argument.
app.ticker.add(delta => gameLoop(delta));
}
function gameLoop(delta){
//Move the cat 1 pixel
cat.x += 1;
}cat.x += 1;
cat.x += 1 + delta;
function gameLoop() {
//Call this `gameLoop` function on the next screen refresh
//(which happens 60 times per second)
requestAnimationFrame(gameLoop);
//Move the cat
cat.x += 1;
}
//Start the loop
gameLoop();//Aliases
let Application = PIXI.Application,
Container = PIXI.Container,
loader = PIXI.loader,
resources = PIXI.loader.resources,
TextureCache = PIXI.utils.TextureCache,
Sprite = PIXI.Sprite,
Rectangle = PIXI.Rectangle;
//Create a Pixi Application
let app = new Application({
width: 256,
height: 256,
antialias: true,
transparent: false,
resolution: 1
}
);
//Add the canvas that Pixi automatically created for you to the HTML document
document.body.appendChild(app.view);
loader
.add("images/cat.png")
.load(setup);
//Define any variables that are used in more than one function
let cat;
function setup() {
//Create the `cat` sprite
cat = new Sprite(resources["images/cat.png"].texture);
cat.y = 96;
app.stage.addChild(cat);
//Start the game loop
app.ticker.add(delta => gameLoop(delta));
}
function gameLoop(delta){
//Move the cat 1 pixel
cat.x += 1;
//Optionally use the `delta` value
//cat.x += 1 + delta;
}使用速度属性
cat.vx = 0; cat.vy = 0;
function setup() {
//Create the `cat` sprite
cat = new Sprite(resources["images/cat.png"].texture);
cat.y = 96;
cat.vx = 0;
cat.vy = 0;
app.stage.addChild(cat);
//Start the game loop
app.ticker.add(delta => gameLoop(delta));
}
function gameLoop(delta){
//Update the cat's velocity
cat.vx = 1;
cat.vy = 1;
//Apply the velocity values to the cat's
//position to make it move
cat.x += cat.vx;
cat.y += cat.vy;
}游戏状态
//Set the game state
state = play;
//Start the game loop
app.ticker.add(delta => gameLoop(delta));
function gameLoop(delta){
//Update the current game state:
state(delta);
}
function play(delta) {
//Move the cat 1 pixel to the right each frame
cat.vx = 1
cat.x += cat.vx;
}//Define any variables that are used in more than one function
let cat, state;
function setup() {
//Create the `cat` sprite
cat = new Sprite(resources["images/cat.png"].texture);
cat.y = 96;
cat.vx = 0;
cat.vy = 0;
app.stage.addChild(cat);
//Set the game state
state = play;
//Start the game loop
app.ticker.add(delta => gameLoop(delta));
}
function gameLoop(delta){
//Update the current game state:
state(delta);
}
function play(delta) {
//Move the cat 1 pixel to the right each frame
cat.vx = 1
cat.x += cat.vx;
}键盘移动
function keyboard(keyCode) {
let key = {};
key.code = keyCode;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
//The `downHandler`
key.downHandler = event => {
if (event.keyCode === key.code) {
if (key.isUp && key.press) key.press();
key.isDown = true;
key.isUp = false;
}
event.preventDefault();
};
//The `upHandler`
key.upHandler = event => {
if (event.keyCode === key.code) {
if (key.isDown && key.release) key.release();
key.isDown = false;
key.isUp = true;
}
event.preventDefault();
};
//Attach event listeners
window.addEventListener(
"keydown", key.downHandler.bind(key), false
);
window.addEventListener(
"keyup", key.upHandler.bind(key), false
);
return key;
}let keyObject = keyboard(asciiKeyCodeNumber);
keyObject.press = () => {
//key object pressed
};
keyObject.release = () => {
//key object released
};//Define any variables that are used in more than one function
let cat, state;
function setup() {
//Create the `cat` sprite
cat = new Sprite(resources["images/cat.png"].texture);
cat.y = 96;
cat.vx = 0;
cat.vy = 0;
app.stage.addChild(cat);
//Capture the keyboard arrow keys
let left = keyboard(37),
up = keyboard(38),
right = keyboard(39),
down = keyboard(40);
//Left arrow key `press` method
left.press = () => {
//Change the cat's velocity when the key is pressed
cat.vx = -5;
cat.vy = 0;
};
//Left arrow key `release` method
left.release = () => {
//If the left arrow has been released, and the right arrow isn't down,
//and the cat isn't moving vertically:
//Stop the cat
if (!right.isDown && cat.vy === 0) {
cat.vx = 0;
}
};
//Up
up.press = () => {
cat.vy = -5;
cat.vx = 0;
};
up.release = () => {
if (!down.isDown && cat.vx === 0) {
cat.vy = 0;
}
};
//Right
right.press = () => {
cat.vx = 5;
cat.vy = 0;
};
right.release = () => {
if (!left.isDown && cat.vy === 0) {
cat.vx = 0;
}
};
//Down
down.press = () => {
cat.vy = 5;
cat.vx = 0;
};
down.release = () => {
if (!up.isDown && cat.vx === 0) {
cat.vy = 0;
}
};
//Set the game state
state = play;
//Start the game loop
app.ticker.add(delta => gameLoop(delta));
}
function gameLoop(delta){
//Update the current game state:
state(delta);
}
function play(delta) {
//Use the cat's velocity to make it move
cat.x += cat.vx;
cat.y += cat.vy
}给精灵分组
//The cat let cat = new Sprite(id["cat.png"]); cat.position.set(16, 16); //The hedgehog let hedgehog = new Sprite(id["hedgehog.png"]); hedgehog.position.set(32, 32); //The tiger let tiger = new Sprite(id["tiger.png"]); tiger.position.set(64, 64);
let animals = new Container();
animals.addChild(cat); animals.addChild(hedgehog); animals.addChild(tiger);
app.stage.addChild(animals);
console.log(animals.children)//Displays: Array [Object, Object, Object]
animals.position.set(64, 64);
console.log(animals.width); //Displays: 112 console.log(animals.height); //Displays: 112
animals.width = 200; animals.height = 200;
局部位置和全局位置
console.log(cat.x);//Displays: 16
parentSprite.toGlobal(childSprite.position)
console.log(animals.toGlobal(cat.position));//Displays: Object {x: 80, y: 80...};cat.parent.toGlobal(cat.position);
tiger.getGlobalPosition().x tiger.getGlobalPosition().y
sprite.toLocal(sprite.position, anyOtherSprite)
tiger.toLocal(tiger.position, hedgehog).x tiger.toLocal(tiger.position, hedgehog).y
使用 ParticleContainer 分组精灵
let superFastSprites = new PIXI.particles.ParticleContainer();
let superFastSprites = new ParticleContainer(maxSize, properties, batchSize, autoResize);
let superFastSprites = new ParticleContainer(
size,
{
rotation: true,
alphaAndtint: true,
scale: true,
uvs: true
}
);用Pixi绘制几何图形
矩形
let rectangle = new Graphics();
rectangle.beginFill(0x66CCFF);
rectangle.lineStyle(4, 0xFF3300, 1);
rectangle.drawRect(x, y, width, height);
rectangle.endFill();
let rectangle = new Graphics(); rectangle.lineStyle(4, 0xFF3300, 1); rectangle.beginFill(0x66CCFF); rectangle.drawRect(0, 0, 64, 64); rectangle.endFill(); rectangle.x = 170; rectangle.y = 170; app.stage.addChild(rectangle);
圆形
drawCircle(x, y, radius)
let circle = new Graphics(); circle.beginFill(0x9966FF); circle.drawCircle(0, 0, 32); circle.endFill(); circle.x = 64; circle.y = 130; app.stage.addChild(circle);
椭圆
drawEllipse(x, y, width, height);
let ellipse = new Graphics(); ellipse.beginFill(0xFFFF00); ellipse.drawEllipse(0, 0, 50, 20); ellipse.endFill(); ellipse.x = 180; ellipse.y = 130; app.stage.addChild(ellipse);
圆角矩形
drawRoundedRect(x, y, width, height, cornerRadius)
let roundBox = new Graphics(); roundBox.lineStyle(4, 0x99CCFF, 1); roundBox.beginFill(0xFF9933); roundBox.drawRoundedRect(0, 0, 84, 36, 10) roundBox.endFill(); roundBox.x = 48; roundBox.y = 190; app.stage.addChild(roundBox);
线段
let line = new Graphics(); line.lineStyle(4, 0xFFFFFF, 1); line.moveTo(0, 0); line.lineTo(80, 50); line.x = 32; line.y = 32; app.stage.addChild(line);
多边形
let path = [ point1X, point1Y, point2X, point2Y, point3X, point3Y ]; graphicsObject.drawPolygon(path);
let triangle = new Graphics(); triangle.beginFill(0x66FF33); //Use `drawPolygon` to define the triangle as //a path array of x/y positions triangle.drawPolygon([ -32, 64, //First point 32, 64, //Second point 0, 0 //Third point ]); //Fill shape's color triangle.endFill(); //Position the triangle after you've drawn it. //The triangle's x/y position is anchored to its first point in the path triangle.x = 180; triangle.y = 22; app.stage.addChild(triangle);
显示文本
let message = new Text("Hello Pixi!");
app.stage.addChild(message);message.position.set(54, 96);
let style = new TextStyle({
fontFamily: "Arial",
fontSize: 36,
fill: "white",
stroke: '#ff3300',
strokeThickness: 4,
dropShadow: true,
dropShadowColor: "#000000",
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6,
});let message = new Text("Hello Pixi!", style);message.text = "Text changed!";
message.style = {fill: "black", font: "16px PetMe64"};message.style = {wordWrap: true, wordWrapWidth: 100, align: center};@font-face {
font-family: "fontFamilyName";
src: url("fonts/fontFile.ttf");
}碰撞检测
hitTestRectangle(spriteOne, spriteTwo)
if (hitTestRectangle(cat, box)) {
//There's a collision
} else {
//There's no collision
}function play(delta) {
//use the cat's velocity to make it move
cat.x += cat.vx;
cat.y += cat.vy;
//check for a collision between the cat and the box
if (hitTestRectangle(cat, box)) {
//if there's a collision, change the message text
//and tint the box red
message.text = "hit!";
box.tint = 0xff3300;
} else {
//if there's no collision, reset the message
//text and the box's color
message.text = "No collision...";
box.tint = 0xccff99;
}
}message.text = "Hit!";
box.tint = 0xff3300;
message.text = "No collision..."; box.tint = 0xccff99;
碰撞检测函数
function hitTestRectangle(r1, r2) {
//Define the variables we'll need to calculate
let hit, combinedHalfWidths, combinedHalfHeights, vx, vy;
//hit will determine whether there's a collision
hit = false;
//Find the center points of each sprite
r1.centerX = r1.x + r1.width / 2;
r1.centerY = r1.y + r1.height / 2;
r2.centerX = r2.x + r2.width / 2;
r2.centerY = r2.y + r2.height / 2;
//Find the half-widths and half-heights of each sprite
r1.halfWidth = r1.width / 2;
r1.halfHeight = r1.height / 2;
r2.halfWidth = r2.width / 2;
r2.halfHeight = r2.height / 2;
//Calculate the distance vector between the sprites
vx = r1.centerX - r2.centerX;
vy = r1.centerY - r2.centerY;
//Figure out the combined half-widths and half-heights
combinedHalfWidths = r1.halfWidth + r2.halfWidth;
combinedHalfHeights = r1.halfHeight + r2.halfHeight;
//Check for a collision on the x axis
if (Math.abs(vx) < combinedHalfWidths) {
//A collision might be occuring. Check for a collision on the y axis
if (Math.abs(vy) < combinedHalfHeights) {
//There's definitely a collision happening
hit = true;
} else {
//There's no collision on the y axis
hit = false;
}
} else {
//There's no collision on the x axis
hit = false;
}
//`hit` will be either `true` or `false`
return hit;
};实例学习: 宝物猎人
代码结构
//Setup Pixi and load the texture atlas files - call the `setup`
//function when they've loaded
function setup() {
//Initialize the game sprites, set the game `state` to `play`
//and start the 'gameLoop'
}
function gameLoop(delta) {
//Runs the current game `state` in a loop and renders the sprites
}
function play(delta) {
//All the game logic goes here
}
function end() {
//All the code that should run at the end of the game
}
//The game's helper functions:
//`keyboard`, `hitTestRectangle`, `contain` and `randomInt`用 setup 函数初始化游戏
function setup() {
//Create the `gameScene` group
//Create the `door` sprite
//Create the `player` sprite
//Create the `treasure` sprite
//Make the enemies
//Create the health bar
//Add some text for the game over message
//Create a `gameOverScene` group
//Assign the player's keyboard controllers
//set the game state to `play`
state = play;
//Start the game loop
app.ticker.add(delta => gameLoop(delta));
}gameScene = new Container(); app.stage.addChild(gameScene); gameOverScene = new Container(); app.stage.addChild(gameOverScene);
gameOverScene.visible = false;
//Create an alias for the texture atlas frame ids id = resources["images/treasureHunter.json"].textures; //Dungeon dungeon = new Sprite(id["dungeon.png"]); gameScene.addChild(dungeon); //Door door = new Sprite(id["door.png"]); door.position.set(32, 0); gameScene.addChild(door); //Explorer explorer = new Sprite(id["explorer.png"]); explorer.x = 68; explorer.y = gameScene.height / 2 - explorer.height / 2; explorer.vx = 0; explorer.vy = 0; gameScene.addChild(explorer); //Treasure treasure = new Sprite(id["treasure.png"]); treasure.x = gameScene.width - treasure.width - 48; treasure.y = gameScene.height / 2 - treasure.height / 2; gameScene.addChild(treasure);
let numberOfBlobs = 6,
spacing = 48,
xOffset = 150,
speed = 2,
direction = 1;
//An array to store all the blob monsters
blobs = [];
//Make as many blobs as there are `numberOfBlobs`
for (let i = 0; i < numberOfBlobs; i++) {
//Make a blob
let blob = new Sprite(id["blob.png"]);
//Space each blob horizontally according to the `spacing` value.
//`xOffset` determines the point from the left of the screen
//at which the first blob should be added
let x = spacing * i + xOffset;
//Give the blob a random `y` position
let y = randomInt(0, stage.height - blob.height);
//Set the blob's position
blob.x = x;
blob.y = y;
//Set the blob's vertical velocity. `direction` will be either `1` or
//`-1`. `1` means the enemy will move down and `-1` means the blob will
//move up. Multiplying `direction` by `speed` determines the blob's
//vertical direction
blob.vy = speed * direction;
//Reverse the direction for the next blob
direction *= -1;
//Push the blob into the `blobs` array
blobs.push(blob);
//Add the blob to the `gameScene`
gameScene.addChild(blob);
}//Create the health bar healthBar = new PIXI.DisplayObjectContainer(); healthBar.position.set(stage.width - 170, 4) gameScene.addChild(healthBar); //Create the black background rectangle let innerBar = new PIXI.Graphics(); innerBar.beginFill(0x000000); innerBar.drawRect(0, 0, 128, 8); innerBar.endFill(); healthBar.addChild(innerBar); //Create the front red rectangle let outerBar = new PIXI.Graphics(); outerBar.beginFill(0xFF3300); outerBar.drawRect(0, 0, 128, 8); outerBar.endFill(); healthBar.addChild(outerBar); healthBar.outer = outerBar;
healthBar.outer = outerBar;
healthBar.outer.width = 30;
let style = new TextStyle({
fontFamily: "Futura",
fontSize: 64,
fill: "white"
});
message = new Text("The End!", style);
message.x = 120;
message.y = app.stage.height / 2 - 32;
gameOverScene.addChild(message);开始游戏
function play(delta) {
//Move the explorer and contain it inside the dungeon
//Move the blob monsters
//Check for a collision between the blobs and the explorer
//Check for a collision between the explorer and the treasure
//Check for a collision between the treasure and the door
//Decide whether the game has been won or lost
//Change the game `state` to `end` when the game is finsihed
}移动探险者
explorer.x += explorer.vx; explorer.y += explorer.vy;
contain(explorer, {x: 28, y: 10, width: 488, height: 480});function contain(sprite, container) {
let collision = undefined;
//Left
if (sprite.x < container.x) {
sprite.x = container.x;
collision = "left";
}
//Top
if (sprite.y < container.y) {
sprite.y = container.y;
collision = "top";
}
//Right
if (sprite.x + sprite.width > container.width) {
sprite.x = container.width - sprite.width;
collision = "right";
}
//Bottom
if (sprite.y + sprite.height > container.height) {
sprite.y = container.height - sprite.height;
collision = "bottom";
}
//Return the `collision` value
return collision;
}移动怪物
blobs.forEach(function(blob) {
//Move the blob
blob.y += blob.vy;
//Check the blob's screen boundaries
let blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480});
//If the blob hits the top or bottom of the stage, reverse
//its direction
if (blobHitsWall === "top" || blobHitsWall === "bottom") {
blob.vy *= -1;
}
//Test for a collision. If any of the enemies are touching
//the explorer, set `explorerHit` to `true`
if(hitTestRectangle(explorer, blob)) {
explorerHit = true;
}
});let blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480});if (blobHitsWall === "top" || blobHitsWall === "bottom") {
blob.vy *= -1;
}检测碰撞
if(hitTestRectangle(explorer, blob)) {
explorerHit = true;
}if(explorerHit) {
//Make the explorer semi-transparent
explorer.alpha = 0.5;
//Reduce the width of the health bar's inner rectangle by 1 pixel
healthBar.outer.width -= 1;
} else {
//Make the explorer fully opaque (non-transparent) if it hasn't been hit
explorer.alpha = 1;
}if (hitTestRectangle(explorer, treasure)) {
treasure.x = explorer.x + 8;
treasure.y = explorer.y + 8;
}处理到达出口和结束游戏
if (hitTestRectangle(treasure, door)) {
state = end;
message.text = "You won!";
}if (healthBar.outer.width < 0) {
state = end;
message.text = "You lost!";
}state = end;
function gameLoop(delta){
//Update the current game state:
state(delta);
}function end() {
gameScene.visible = false;
gameOverScene.visible = true;
}
查看更多关于js pixi框架 极其详细到位(入门)-----转载的详细内容...