package gameEngine.entites.gameComponents; import gameEngine.entites.Entity; import gameEngine.entites.GameObject; import gameEngine.views.Color; import gameEngine.views.Texture; import gameEngine.views.Window; import static org.lwjgl.opengl.GL11.*; public class Mesh extends GameComponent { public enum MeshType { SPRITE, CUBE } private final MeshType type; private Texture texture; // スプライトのテクスチャを保持 private final Entity parent; // 親のオブジェクトを持つ private Color color = new Color(1f, 1f, 1f, 1f); private int spriteWidth = 64; // スプライト幅(今後指定可能にする) private int spriteHeight = 64; // スプライト高さ(今後指定可能にする) public Mesh(Entity parent, MeshType type, String texturePath) { this.parent = parent; this.type = type; if (type == MeshType.SPRITE) { this.texture = new Texture(texturePath); // Load the image updateSpriteDimensions(); } } public Mesh(Mesh original, Entity newParent) { this.type = original.type; this.texture = original.texture; // Textureをそのまま参照 this.parent = newParent; // 新しい親オブジェクトに設定 updateSpriteDimensions(); } @Override public GameComponent copy() { return this; } @Override public void init() { if (type == MeshType.SPRITE) { renderSprite(); // スプライトの描画 updateSpriteDimensions(); } } @Override public void update() { if (type == MeshType.SPRITE) { Integer id = texture.getId(); if(id == null){ texture.init(); } renderSprite(); // スプライトの描画 } } /** * メッシュのカラーを変更 * */ public void setColor(Color color){ this.color = color; renderSprite(); } /** * スプライトの最終的な表示幅を取得 * @return 表示幅(スケールとZスケールを考慮したサイズ) */ public float getDisplayedWidth() { float zScale = calculateZScale(); return spriteWidth * parent.transform.scale.x * zScale; } /** * スプライトの最終的な表示高さを取得 * @return 表示高さ(スケールとZスケールを考慮したサイズ) */ public float getDisplayedHeight() { float zScale = calculateZScale(); return spriteHeight * parent.transform.scale.y * zScale; } /** * Z軸スケールを計算する * @return 計算されたZ軸スケール */ private float calculateZScale() { float z = parent.transform.position.z; if (z >= 0) { return 1.0f + (z * 0.1f); } else { return 1.0f / (1.0f + Math.abs(z) * 0.1f); } } private void updateSpriteDimensions() { if (texture != null) { this.spriteWidth = texture.getWidth(); this.spriteHeight = texture.getHeight(); } } public void setTexturePath(String texturePath){ this.texture = new Texture(texturePath); updateSpriteDimensions(); } private void renderSprite() { // 2Dの描画モードに切り替え glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // ピクセル単位の座標系に設定 glOrtho(0, Window.get().width, Window.get().height, 0, -1000, 1000); // モデルビュー行列に切り替えて描画する位置を決める glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); // テクスチャをバインド glBindTexture(GL_TEXTURE_2D, texture.getId()); // 親のGameObjectの座標と回転を取得 float x = parent.transform.position.x; float y = parent.transform.position.y; float z = parent.transform.position.z; float rotationZ = parent.transform.rotation.z; float scaleX = parent.transform.scale.x; float scaleY = parent.transform.scale.y; float zScale; if (z >= 0) { zScale = 1.0f + (z * 0.1f); } else { zScale = 1.0f / (1.0f + Math.abs(z) * 0.1f); } // 左上基準でスケーリング glTranslatef(x, y, z); glScalef(scaleX * zScale, scaleY * zScale, 1.0f); // スケールを適用 glRotatef(rotationZ, 0, 0, 1); // Z軸周りの回転 // テクスチャの描画設定 glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(color.r, color.g, color.b, color.a); // 四角形を描画 glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3f(0, 0, 0); // 左上の頂点 glTexCoord2f(1, 0); glVertex3f(spriteWidth, 0, 0); // 右上の頂点 glTexCoord2f(1, 1); glVertex3f(spriteWidth, spriteHeight, 0); // 右下の頂点 glTexCoord2f(0, 1); glVertex3f(0, spriteHeight, 0); // 左下の頂点 glEnd(); // テクスチャの使用を終了 glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); // 行列を元に戻す glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); } }