User prompt
Please fix the bug: 'Timeout.tick error: playerBustFlow is not defined' in or related to this line: 'playerBustFlow(); // ← senin iflasın' Line Number: 2471
User prompt
Oynama sırası 1. oyuncuya geldiği zaman 1. oyuncu DEVAM tuşu pasif bile olsa DEVAM tuşuna basıp 6 zarı tekrar atabiliyor. Bunu düzeltmen lazım. Pasif olan DEVAM tuşuna nasıl basılabiliyor? Bunu çöz!
Code edit (10 edits merged)
Please save this source code
User prompt
diceStatKeys'nin yani hangi zardan kaç tane geldiğini gösteren yerin biraz üstüne gri renkle "Tur sonunda hedef skora ilk ulaşan oyuncu kazanır. Her iki oyuncunun da hedefe ulaşması durumunda skorlar sıfırlanır ve oyun devam eder." yazısı yazın istiyorum.
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: LANGS is not defined' in or related to this line: 'var iflasTxt = new Text2(LANGS[getLanguage()].bust, {' Line Number: 2243
User prompt
Please fix the bug: 'Uncaught ReferenceError: getLanguage is not defined' in or related to this line: 'var lang = getLanguage();' Line Number: 1958
User prompt
Please fix the bug: 'Uncaught ReferenceError: getLanguage is not defined' in or related to this line: 'var lang = getLanguage();' Line Number: 1939
User prompt
Please fix the bug: 'Uncaught ReferenceError: LANGS is not defined' in or related to this line: 'var infoTxt = new Text2(LANGS[getLanguage()].info, {' Line Number: 1939
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'winRate')' in or related to this line: 'window.winRateTxt.setText(t.winRate + ": " + winRateStr + " | " + t.matchCount + ": " + oyunSayisiStr + " | " + t.level + ": " + level);' Line Number: 1802
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'winRate')' in or related to this line: 'window.winRateTxt.setText(t.winRate + ": " + winRateStr + " | " + t.matchCount + ": " + oyunSayisiStr + " | " + t.level + ": " + level);' Line Number: 1802
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // geri düş: ms cinsinden epoch // Konfeti Parçacığı Sınıfı var ConfettiParticle = Container.expand(function () { var self = Container.call(this); // Rastgele renk ve şekil seç function randomColor() { // Canlı, pastel ve koyu renkler karışık var palette = [[255, 59, 59], // kırmızı [59, 255, 59], // yeşil [59, 59, 255], // mavi [255, 224, 102], // sarı [102, 224, 255], // açık mavi [255, 102, 224], // pembe [255, 255, 255], // beyaz [255, 165, 0], // turuncu [0, 230, 230], // cam göbeği [142, 68, 173], // mor [46, 204, 64], // koyu yeşil [243, 156, 18], // altın sarısı [231, 76, 60], // canlı kırmızı [22, 160, 133], // teal [52, 73, 94], // koyu mavi [255, 192, 203], // pastel pembe [173, 216, 230], // pastel mavi [255, 255, 153], // pastel sarı [204, 255, 204], // pastel yeşil [255, 153, 204] // pastel fuşya ]; var idx = Math.floor(Math.random() * palette.length); var rgb = palette[idx]; // RGB to hex return (rgb[0] << 16) + (rgb[1] << 8) + rgb[2]; } var color = randomColor(); var shapeType = Math.random() < 0.5 ? 'box' : 'ellipse'; // Rastgele boyut var size = 32 + Math.floor(Math.random() * 32); // Asset oluştur // 'confettiShape' adında bir shape asset'i kullanıyoruz (id önemli değil, motor otomatik oluşturur) var asset = self.attachAsset('confettiShape', { width: size, height: size, anchorX: .5, anchorY: .5 }); asset.tint = color; // Başlangıç pozisyonu: X rastgele, Y üstte self.x = 80 + Math.random() * (2048 - 160); self.y = -40 - Math.random() * 80; // Rastgele hız ve açı self.vy = 3 + Math.random() * 3; // Düşme hızı self.vx = -2 + Math.random() * 4; // Sağa/sola savrulma self.spin = -0.05 + Math.random() * 0.1; // Hafif dönme // Hafifçe şeffaflık asset.alpha = 0.85 + Math.random() * 0.15; // Hafifçe farklı ölçek asset.scaleX = 0.8 + Math.random() * 0.6; asset.scaleY = 0.8 + Math.random() * 0.6; // Dönme açısı asset.rotation = Math.random() * Math.PI * 2; // Son pozisyonları takip et (gerekirse) self.lastY = self.y; // Her frame güncelle self.update = function () { self.x += self.vx; self.y += self.vy; asset.rotation += self.spin; // Hafifçe sağa/sola dalgalanma self.vx += -0.1 + Math.random() * 0.2; // Ekran dışına çıktıysa yok et if (self.y > 2732 + 60) { if (self.parent) { self.parent.removeChild(self); } self._destroyed = true; } }; return self; }); /**** * Initialize Game ****/ /*********************************************************** * 1. KISIM — VARLIKLAR, GENEL TANIMLAR, Dice SINIFI ************************************************************/ /* --- Zar sınıfı --- */ // Joker zarı için (zar6 ile aynı görsel, gerekirse farklı id ile değiştir) // Kanvas boyutları /* --- Oyun nesnesi --- */ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ /* === AI globals & stats ================================= */ /* ---------------- NPC Pattern Tabloları ---------------- */ // 1-5 listelerinde _sıralı string_ kullanıyoruz (örn: "115"). function _typeof6(o) { "@babel/helpers - typeof"; return _typeof6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof6(o); } function _typeof5(o) { "@babel/helpers - typeof"; return _typeof5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof5(o); } function _typeof4(o) { "@babel/helpers - typeof"; return _typeof4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof4(o); } var BUST_PASS_DELAY = 600; var DICE_Y_OFFSET = 40; var CONTINUE_PATTERNS = { 6: ["1", "5", "11", "55", "15", "115", "155", "1155"], 5: ["1", "5", "11", "55", "15", "115", "155"], 4: ["1", "5", "11", "55", "15"], 3: ["1", "5", "55"], // “1 5” burada yok –> 3 zarla banklamak istiyorsun 2: ["5"], // sadece tek 5 1: ["5"] // tek 5 }; var NPC_STEP_DELAY = 1000; // 1 saniye function applyFinalDecision() { // BANK mi DEVAM mı zaten bestMoveBank değişkeninde if (bestMoveBank) { var _LK$getSound; (_LK$getSound = LK.getSound('tutVeTuruSonlandirSesi')) === null || _LK$getSound === void 0; // 1 sn boyunca seçili zarlar ekranda kalsın LK.setTimeout(function () { var _bestMove$score, _bestMove; selectedScores[NPC] = (_bestMove$score = (_bestMove = bestMove) === null || _bestMove === void 0 ? void 0 : _bestMove.score) !== null && _bestMove$score !== void 0 ? _bestMove$score : 0; tempScores[NPC] += selectedScores[NPC]; scores[NPC] += tempScores[NPC]; tempScores[NPC] = selectedScores[NPC] = 0; updateHUD(); endTurn(); }, NPC_STEP_DELAY); } else { var _bestMove$score3, _bestMove3; var _LK$getSound2, _bestMove$score2, _bestMove2; (_LK$getSound2 = LK.getSound('tutVeDevamEtSesi')) === null || _LK$getSound2 === void 0; /* 1. Skoru ekle */ selectedScores[NPC] = (_bestMove$score3 = (_bestMove3 = bestMove) === null || _bestMove3 === void 0 ? void 0 : _bestMove3.score) !== null && _bestMove$score3 !== void 0 ? _bestMove$score3 : 0; tempScores[NPC] += selectedScores[NPC]; selectedScores[NPC] = 0; /* 2. Zarları henüz silme! – önce yeni atış gösterilsin */ updateHUD(); // seçili zarlar masada, sayılar güncel /* 3. Kalan zarları döndür; silme işini callback’te yapacağız */ var toErase = dice.filter(function (d) { return d.selected; }); // referans tut animateRoll(function () { /* 3.a Seçili zarları ANCAK yeni değerler göründükten sonra kaldır */ dice = dice.filter(function (d) { return !toErase.includes(d); }); selectedDiceIdx = []; if (dice.length === 0) { handleHotDice(function () { // oyuncu ise hiçbir şey yapma / NPC ise npcQuickDecision }); return; // alttaki akışı atla } else { dice.forEach(function (d) { d.selected = false; }); renumberDice(); updateDicePositions(); } var leftVals = dice.map(function (d) { return d.value; }); if (!canMakeAnyScore(leftVals)) { npcBustFlow(); } else { LK.setTimeout(npcQuickDecision, NPC_STEP_DELAY); } }, false); } } /* ––– YALNIZ BANKLAMADA KULLANILACAK ––– * Elinizdeki zarlar arasından PUAN GETİREN * Tüm alt–kümeleri tarar, en yüksek skorluyu döndürür. * Hiç puanlı seçim yoksa null döner. */ function bestScoringCombo(vals) { var best = null, bestScore = -1; for (var k = 1; k <= vals.length; k++) { getCombinations(vals, k).forEach(function (c) { if (isValidSelection(c)) { var s = calcScoreFarkle(c).score; if (s > bestScore) { bestScore = s; best = c; } } }); } return best ? { combo: best, score: bestScore } : { combo: [], score: 0 }; } function handleHotDice(continueCallback) { resetDice(6, false); // yeni zarları ekle animateRoll(function () { var leftVals = dice.map(function (d) { return d.value; }); if (!canMakeAnyScore(leftVals)) { npcBustFlow ? npcBustFlow() : endTurn(); } else { continueCallback(); // NPC’de npcQuickDecision, oyuncuda pas geç vb. } }); } var lastCombos = null; function _createForOfIteratorHelper4(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray4(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n4 = 0, F = function F() {}; return { s: F, n: function n() { return _n4 >= r.length ? { done: !0 } : { done: !1, value: r[_n4++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _unsupportedIterableToArray4(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray4(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray4(r, a) : void 0; } } function _arrayLikeToArray4(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } function _typeof3(o) { "@babel/helpers - typeof"; return _typeof3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof3(o); } function _typeof2(o) { "@babel/helpers - typeof"; return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof2(o); } function _classCallCheck2(a, n) { if (!(a instanceof n)) { throw new TypeError("Cannot call a class as a function"); } } function __defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey2(o.key), o); } } function _createClass2(e, r, t) { return r && __defineProperties(e.prototype, r), t && __defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _toPropertyKey2(t) { var i = _toPrimitive2(t, "string"); return "symbol" == _typeof2(i) ? i : i + ""; } function _toPrimitive2(t, r) { if ("object" != _typeof2(t) || !t) { return t; } var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof2(i)) { return i; } throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } var bestMove = null, bestMoveBank = false, bestMoveScore = -Infinity; var perfNow = typeof performance !== 'undefined' && typeof performance.now === 'function' ? performance.now.bind(performance) : function () { return Date.now(); }; // yüksek çözünürlüklü süre // Konfeti renkleri (dilediğin kadar ekleyebilirsin) // --- Konfeti Efekti için Global Değişkenler ve Sınıf --- // Music for each screen var CONFETTI_COLORS = [0xA020F0, 0x008000, 0xFF7F00, 0x0000C8, 0xff3b3b, 0x3bff3b, 0x3b3bff, 0xffe066, 0x66e0ff, 0xff66e0, 0xffffff, 0xffa500, 0x00e6e6, 0xff0000, 0xffff00, 0x000000, 0xFFFFFF]; // Konfeti parçacıklarını tutan dizi var confettiParticles = []; // Konfeti efektinin interval referansı var confettiInterval = null; // utils.js – script’in başına ekle function randomDiceValue() { var r = Math.random(); if (r < 0.04) { return 0; } // %4 Joker if (r < 0.20) { return 1; } // %16 if (r < 0.36) { return 2; } // %16 if (r < 0.52) { return 3; } // %16 if (r < 0.68) { return 4; } // %16 if (r < 0.84) { return 5; } // %16 return 6; // %16 (r ≥ 0.84) } function enumerateRolls(n, buf, out) { buf = buf || []; out = out || []; if (buf.length === n) { out.push(buf.slice()); return out; } for (var v = 1; v <= 6; v++) { buf.push(v); enumerateRolls(n, buf, out); buf.pop(); } return out; } /* --- Zar sınıfı --- */ // Joker zarı için (zar6 ile aynı görsel, gerekirse farklı id ile değiştir) function _createForOfIteratorHelper3(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray3(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n3 = 0, F = function F() {}; return { s: F, n: function n() { return _n3 >= r.length ? { done: !0 } : { done: !1, value: r[_n3++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _unsupportedIterableToArray3(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray3(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray3(r, a) : void 0; } } function _arrayLikeToArray3(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } function _createForOfIteratorHelper2(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray2(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n2 = 0, F = function F() {}; return { s: F, n: function n() { return _n2 >= r.length ? { done: !0 } : { done: !1, value: r[_n2++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _unsupportedIterableToArray2(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray2(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a) : void 0; } } function _arrayLikeToArray2(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } function _arrayWithHoles(r) { if (Array.isArray(r)) { return r; } } function _classCallCheck(a, n) { if (!(a instanceof n)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) { return t; } var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) { return i; } throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) { return e; } if (void 0 !== e) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(t); } function _assertThisInitialized(e) { if (void 0 === e) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return e; } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } function _inherits(t, e) { if ("function" != typeof e && null !== e) { throw new TypeError("Super expression must either be null or a function"); } t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } var W = 2048, H = 2732; var Dice = /*#__PURE__*/function (_Container) { function Dice() { var _this; _classCallCheck(this, Dice); _this = _callSuper(this, Dice); /** Zar yüzü (1-6) */ _this.value = 1; /** Seçili mi? */ _this.selected = false; // Zar yüzü asset'i (her değer için ayrı) _this.face = _this.attachAsset('zar1', { anchorX: .5, anchorY: .5, width: 310, height: 310 }); _this.updateFace = function () { // Eski asset'i kaldır if (_this.face && _this.face.parent) { _this.face.parent.removeChild(_this.face); } // Yeni asset'i ekle var assetName = this.value === 0 ? 'zarJoker' : 'zar' + this.value; _this.face = _this.attachAsset(assetName, { anchorX: .5, anchorY: .5, width: 310, height: 310 }); }; // Başlangıçta 1 ile başlat _this.value = 1; _this.selected = false; _this.updateFace(); return _this; } /** Değeri ayarla + yüzü güncelle */ _inherits(Dice, _Container); return _createClass(Dice, [{ key: "setValue", value: function setValue(v) { this.value = v; this.updateFace(); } }]); }(Container); // --- Global durum --- */ var PLAYER = 0, NPC = 1; var scores = [0, 0], turnScore = 0, current = PLAYER, gameOver = false; var dice = []; // Aktif zarlar var selectedDiceIdx = []; // Seçili zar indeksleri var diceGroup = null, selectedDiceGroup = null; // --- Oyun Devamı için Geçici Kayıt/Restore --- // Kaydedilecek anahtarlar: scores, tempScores, selectedScores, turnScore, turnNumber, current, diceVals, selectedDiceIdx, gameOver function saveGameState() { // Sadece oyun devam ediyorsa kaydet if (gameOver) { if (typeof storage !== "undefined" && storage) { storage.tempGameState = null; } return; } var diceVals = dice.map(function (d) { return d.value; }); var diceSelected = dice.map(function (d) { return !!d.selected; }); if (typeof storage !== "undefined" && storage) { try { storage.tempGameState = { scores: scores.slice(), tempScores: tempScores.slice(), selectedScores: selectedScores.slice(), turnScore: turnScore, turnNumber: turnNumber, current: current, diceVals: diceVals, diceSelected: diceSelected, selectedDiceIdx: selectedDiceIdx.slice(), gameOver: gameOver }; } catch (e) { // Defensive: ignore storage errors } } } function restoreGameState() { var state = storage.tempGameState; if (!state || state.gameOver) { return false; } // Restore all main variables scores = state.scores.slice(); tempScores = state.tempScores.slice(); selectedScores = state.selectedScores.slice(); turnScore = state.turnScore; turnNumber = state.turnNumber; current = state.current; gameOver = state.gameOver; // Zarları oluştur ve değerleri ata resetDice(state.diceVals.length, false); for (var i = 0; i < dice.length; i++) { dice[i].setValue(state.diceVals[i]); dice[i].selected = !!state.diceSelected[i]; } selectedDiceIdx = state.selectedDiceIdx.slice(); updateDicePositions(); updateHUD(); return true; } // Oyun sırasında önemli değişikliklerde kaydet function saveGameStateIfNeeded() { // Oyun ekranındayken ve oyun bitmemişse kaydet if (!gameOver && typeof mainMenuContainer === "undefined" || !mainMenuContainer) { saveGameState(); } } // Oyun başında otomatik olarak restore etmeye çalış (function tryRestoreOnLoad() { // Sadece bir kez hook'la, tekrar tekrar sarmalama! if (storage && storage.tempGameState && storage.tempGameState.gameOver !== true) { // Yükleme ekranı kalkınca restore et var origStartGame = startGame; startGame = function startGame() { // Sadece bir kez restore etmeye çalış if (typeof storage !== "undefined" && storage && storage.tempGameState && storage.tempGameState.gameOver !== true) { if (restoreGameState()) { // Oyun arkaplanını güncelle (restoreGameState'de resetDice çağrıldı, burada tekrar ekle) if (game._oyunBg) { game._oyunBg.destroy(); game._oyunBg = null; } var oyunBg = LK.getAsset('oyunEkraniArkaplani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: W, height: H }); game.addChildAt(oyunBg, 0); game._oyunBg = oyunBg; updateHUD(); var ilkSenBasliyorsunSesi = LK.getSound && LK.getSound('ilkSenBasliyorsunSesi'); if (ilkSenBasliyorsunSesi && ilkSenBasliyorsunSesi.play) { ilkSenBasliyorsunSesi.play(); } // Zar animasyonu oynatma (isteğe bağlı, restore sonrası) animateRoll(); return; } } origStartGame(); }; } })(); // Oyun bittiğinde veya ana menüye dönüldüğünde kaydı temizle function clearGameState() { storage.tempGameState = null; } /* --- Diziyi yeniden numaralandır + doğru tıklama --- */ function renumberDice() { for (var i = 0; i < dice.length; i++) { var d = dice[i]; d.idx = i; // güncel indis d.down = function () { toggleSelect(this.idx); }; // <— closure sorunu yok } } /*********************************************************** * 2. KISIM — SKOR HESABI ve KOMBİNASYON YARDIMCILARI ************************************************************/ /* Farkle puan tablosu */ function calcScoreFarkle(vals) { // Joker zarları (0) varsa, onları 1-6'ya çevirerek en yüksek puanı bul var jokerCount = 0; var nonJokerVals = []; for (var i = 0; i < vals.length; i++) { if (vals[i] === 0 || vals[i] === 7) { jokerCount++; } else { nonJokerVals.push(vals[i]); } } if (jokerCount > 0) { // Jokerleri 1-6 arasında tüm kombinasyonlara dağıt var _generateJokerCombos = function generateJokerCombos(arr, jokersLeft, acc, idxMap) { if (jokersLeft === 0) { // acc: nonJokerVals + joker değerleri var testVals = acc.slice(); var res = calcScoreFarkle.noJoker(testVals); if (res.score > maxScore) { maxScore = res.score; // used dizisini orijinal dizideki indekslere göre dönüştür var used = []; var accIdx = 0; for (var i = 0; i < vals.length; i++) { if (vals[i] === 0 || vals[i] === 7) { // Jokerlerden hangisi kullanıldıysa, orijinal indexi ekle if (res.used.includes(accIdx)) { used.push(i); } accIdx++; } else { if (res.used.includes(accIdx)) { used.push(i); } accIdx++; } } bestUsed = used; bestVals = testVals.slice(); } return; } for (var v = 1; v <= 6; v++) { acc.push(v); _generateJokerCombos(arr, jokersLeft - 1, acc, idxMap); acc.pop(); } }; // acc: nonJokerVals + joker değerleri // Tüm olası joker kombinasyonlarını dene ve en yüksek puanı bul var maxScore = -1; var bestUsed = []; var bestVals = []; _generateJokerCombos(nonJokerVals, jokerCount, nonJokerVals.slice(), []); return { score: maxScore > 0 ? maxScore : 0, used: bestUsed }; } // Joker yoksa, normal hesapla return calcScoreFarkle.noJoker(vals); } // Orijinal fonksiyonu sakla (joker olmayanlar için) calcScoreFarkle.noJoker = function (vals) { var cnt = Array(7).fill(0); vals.forEach(function (v) { return cnt[v]++; }); var score = 0, used = []; /* Full straight 1-6 */ if (vals.length === 6 && [1, 2, 3, 4, 5, 6].every(function (v) { return cnt[v] === 1; })) { return { score: 1500, used: [0, 1, 2, 3, 4, 5] }; } /* Partial straight 1-5 */ if (vals.length === 5 && [1, 2, 3, 4, 5].every(function (v) { return cnt[v]; })) { return { score: 500, used: [0, 1, 2, 3, 4] }; } /* Partial straight 2-6 */ if (vals.length === 5 && [2, 3, 4, 5, 6].every(function (v) { return cnt[v]; })) { return { score: 750, used: [0, 1, 2, 3, 4] }; } /* 3-6 aynı zar kümeleri */ for (var v = 1; v <= 6; v++) { if (cnt[v] >= 3) { var base = v === 1 ? 1000 : v * 100; var factor = [1, 2, 4, 8][cnt[v] - 3]; score += base * factor; var need = cnt[v]; vals.forEach(function (val, i) { if (val === v && need) { used.push(i); need--; } }); cnt[v] = 0; // tekil sayılmasın } } /* Tekil 1 & 5 */ vals.forEach(function (v, i) { if (used.includes(i)) { return; } if (v === 1) { score += 100; used.push(i); } if (v === 5) { score += 50; used.push(i); } }); return { score: score, used: used }; }; /***************************************************************** * Eksiksiz olasılık tablosu – oyun açılışında bir kez hesaplanır *****************************************************************/ var exactFarkleTable = {}; // diceLeft → {bust, expected} (function buildExactTable() { for (var diceLeft = 1; diceLeft <= 6; diceLeft++) { var total = 0; // 6^n var bustCount = 0; var scoreSum = 0; // yalnızca skor alınan durumlarda toplanır var faces = Array(diceLeft).fill(0); // kartesyen ürün: 6^diceLeft kombinasyonu tek tek dolaş (function dfs(pos) { if (pos === diceLeft) { total++; var r = calcScoreFarkle(faces); if (r.score === 0) { bustCount++; } else { scoreSum += r.score; } // en yüksek skora göre return; } for (var f = 1; f <= 6; f++) { faces[pos] = f; dfs(pos + 1); } })(0); var bustProb = bustCount / total; var expectedWhenScore = scoreSum / Math.max(1, total - bustCount); // skorlu durumda ort. exactFarkleTable[diceLeft] = { bust: bustProb, expected: expectedWhenScore }; } })(); /* Seçim geçerli mi? */ function isValidSelection(selVals) { var r = calcScoreFarkle(selVals); return r.score > 0 && r.used.length === selVals.length; } /* Belirli uzunlukta kombinasyonları döndür */ function getCombinations(arr, k) { var out = []; (function helper(start, path) { if (path.length === k) { out.push(path.slice()); return; } for (var i = start; i < arr.length; i++) { path.push(arr[i]); helper(i + 1, path); path.pop(); } })(0, []); return out; } /* Kalan zarlarla **hiç** skor yapılabilir mi? */ function canMakeAnyScore(vals) { if (!vals.length) { return false; } for (var i = 1; i <= vals.length; i++) { var combs = getCombinations(vals, i); var _iterator = _createForOfIteratorHelper(combs), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var c = _step.value; if (isValidSelection(c)) { return true; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } return false; } /*********************************************************** * 3. KISIM — GUI, HUD ve ZAR YÖNETİMİ ************************************************************/ /* --- Butonlar --- */ // TUT ve DEVAM ET butonu var rollBtn = new Container(); rollBtn.attachAsset('tutVeDevamEtButonuGorseli', { anchorX: .5, anchorY: .5 }); var rollTxt = new Text2('DEVAM', { size: 80, fill: '#fff' }); rollTxt.anchor.set(.5, .5); rollTxt.y = 40; rollBtn.addChild(rollTxt); LK.gui.bottom.addChild(rollBtn); rollBtn.x = -500; rollBtn.y = -160; // TUT ve TURU SONLANDIR butonu var bankBtn = new Container(); bankBtn.attachAsset('tutVeTuruSonlandirButonuGorseli', { anchorX: .5, anchorY: .5 }); var bankTxt = new Text2('TAMAM', { size: 80, fill: '#fff' }); bankTxt.anchor.set(.5, .5); bankTxt.y = 40; bankBtn.addChild(bankTxt); LK.gui.bottom.addChild(bankBtn); bankBtn.x = 0; bankBtn.y = -160; // PAS GEÇ butonu var passBtn = new Container(); passBtn.attachAsset('pasGecButonuGorseli', { anchorX: .5, anchorY: .5 }); var passTxt = new Text2('PAS', { size: 80, fill: '#fff' }); passTxt.anchor.set(.5, .5); passTxt.y = 40; passBtn.addChild(passTxt); LK.gui.bottom.addChild(passBtn); // PAS GEÇ butonunu TUT ve TURU SONLANDIR butonunun sağına yerleştir passBtn.x = 500; passBtn.y = -160; /* --- Reset & Pozisyon --- */ function resetDice() { var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 6; var randomize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (diceGroup) { diceGroup.destroy(); } if (selectedDiceGroup) { selectedDiceGroup.destroy(); } dice = []; selectedDiceIdx = []; diceGroup = new Container(); selectedDiceGroup = new Container(); game.addChild(diceGroup); game.addChild(selectedDiceGroup); var diceSpacing = 338; var startX = W / 2 - (n - 1) * diceSpacing / 2; var y = H / 2 + DICE_Y_OFFSET; for (var i = 0; i < n; i++) { var d = new Dice(); d.x = startX + i * diceSpacing; d.y = y; if (randomize) { var v = randomDiceValue(); // ← Yeni fonksiyon if (v === 0) { // Joker d.value = 0; if (d.face && d.face.parent) { d.face.parent.removeChild(d.face); } d.face = d.attachAsset('zarJoker', { anchorX: .5, anchorY: .5, width: 310, height: 310 }); } else { d.setValue(v); // 1-6 normal yüz } } diceGroup.addChild(d); dice.push(d); } renumberDice(); updateDicePositions(); updateHUD(); } /* Seç/Aç seçimi */ function toggleSelect(idx) { if (gameOver || current !== PLAYER) { return; } var d = dice[idx]; if (d.selected) { d.selected = false; selectedDiceIdx = selectedDiceIdx.filter(function (i) { return i !== idx; }); // Play zarBirakmaSesi when deselecting var birakmaSesi = LK.getSound && LK.getSound('zarBirakmaSesi'); if (birakmaSesi && birakmaSesi.play) { birakmaSesi.play(); } } else { d.selected = true; if (!selectedDiceIdx.includes(idx)) { selectedDiceIdx.push(idx); } // Play zarSecmeSesi when selecting var secmeSesi = LK.getSound && LK.getSound('zarSecmeSesi'); if (secmeSesi && secmeSesi.play) { secmeSesi.play(); } } updateDicePositions(); updateHUD(); saveGameState(); // Her seçimde kaydet } /* Konumları güncelle */ function updateDicePositions() { if (!diceGroup || !selectedDiceGroup) { return; } diceGroup.removeChildren(); selectedDiceGroup.removeChildren(); // YENİ: her iki oyuncu için d.selected bayrağını kullan var sel = [], unsel = []; for (var i = 0; i < dice.length; i++) { var d = dice[i]; if (!d) { continue; } // güvenlik if (d.selected) { sel.push(i); selectedDiceGroup.addChild(d); } else { unsel.push(i); diceGroup.addChild(d); } } /* Seçili zarlar aşağıda (hem PLAYER hem de NPC için) */ // 2. oyuncu (NPC) için de seçili zarlar aşağıda dizilecek var diceSpacing = 338; var selStart = W / 2 - (sel.length - 1) * diceSpacing / 2; var selY = H / 2 + 338 + DICE_Y_OFFSET; sel.forEach(function (idx, i) { var d = dice[idx]; d.x = selStart + i * diceSpacing; d.y = selY; d.face.alpha = .6; }); /* Diğer zarlar ortada */ var unStart = W / 2 - (unsel.length - 1) * diceSpacing / 2, y = H / 2 + DICE_Y_OFFSET; unsel.forEach(function (idx, i) { var d = dice[idx]; d.x = unStart + i * diceSpacing; d.y = y; d.face.alpha = 1; }); } /**** ZAR DÖNDÜRME ANİMASYONU ****/ function animateRoll(onFinish) { var playSfx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; if (game._rolling) { return; } // Çifte animasyonu engelle game._rolling = true; if (playSfx) { var s = LK.getSound && LK.getSound('tutVeDevamEtSesi'); s === null || s === void 0 || s.play(); } rollBtn.interactive = bankBtn.interactive = passBtn.interactive = false; dice.forEach(function (d) { return d.down = function () {}; }); // Zarlar seçilemesin var rollDuration = 2000, step = 60; var elapsed = 0; (function tick() { dice.forEach(function (d) { if (!d.selected) { var v = randomDiceValue(); d.setValue(v); // Joker dâhil gerçek yüzü göster } }); updateDicePositions(); if ((elapsed += step) < rollDuration) { LK.setTimeout(tick, step); } else { game._rolling = false; rollBtn.interactive = bankBtn.interactive = passBtn.interactive = true; renumberDice(); // Zarlar yeniden seçilebilir // --- Zar istatistiklerini güncelle (sadece oyuncu için) --- if (current === PLAYER) { var playerDiceVals = dice.filter(function (d) { return !d.selected; }).map(function (d) { return d.value; }); updateZarStatsForPlayerDice(playerDiceVals); refreshZarStatsTxt(); } onFinish === null || onFinish === void 0 || onFinish(); // Animasyon tamam callback } })(); } /*********************************************************** * 4. KISIM — OYUN DÖNGÜSÜ, NPC, HUD, BAŞLAT ************************************************************/ // --- HUD --- // Skor tablosu için Text2 objeleri var scoreTableRows = [null, null, null, null]; var turnTxt; var TARGET_SCORE = 8000; // Hedef puan var BANK_BIAS = TARGET_SCORE * 2; /* vuruş anında daha agresif banklama */ var _INFTY = 1e12; // alpha-beta için pratik sonsuz // Geçici ve seçilen skorlar için yeni değişkenler var tempScores = [0, 0]; // Geçici skorlar (her oyuncu için) var selectedScores = [0, 0]; // Seçilen skorlar (her oyuncu için) var turnNumber = 1; // Tur sayısı // --- DİL: Klavye ve skor tablosu için yardımcılar --- // Define getLanguage function globally before it's used function getLanguage() { // Defensive: check LANGS exists and has property if (typeof storage !== "undefined" && storage && typeof storage.lang === "string" && (typeof LANGS === "undefined" ? "undefined" : _typeof6(LANGS)) === "object" && LANGS && Object.prototype.hasOwnProperty.call(LANGS, storage.lang)) { return storage.lang; } return "tr"; } // Klavye tuşlarını güncellemek için fonksiyon function updateKeyboardLabels(container, type) { var lang = getLanguage(); var t = LANGS[lang]; if (!container) return; for (var i = 0; i < container.children.length; i++) { var btn = container.children[i]; if (btn && btn._isKeyBtn && btn.label) { var code = null; if (typeof btn._row !== "undefined" && typeof btn._col !== "undefined" && Array.isArray(btn._row) === false) { // playerNameDialog klavyesi if (type === "playerName") { var keyboardRows = [["A", "B", "C", "Ç", "D", "E", "F", "G", "Ğ"], ["H", "I", "İ", "J", "K", "L", "M", "N", "O"], ["Ö", "P", "R", "S", "Ş", "T", "U", "Ü", "V"], ["Y", "Z", "SPACE", "DEL", "CAPS", "GERI", "TAMAM"]]; code = keyboardRows[btn._row][btn._col]; } else if (type === "reset") { var keyboardRows = [["E", "V", "E", "T"], ["DEL", "GERI", "TAMAM"]]; code = keyboardRows[btn._row][btn._col]; } } if (code === "DEL") { btn.label.setText(t["delete"]); } else if (code === "GERI") { btn.label.setText(t.back); } else if (code === "TAMAM") { btn.label.setText(t.ok); } else if (code === "SPACE") { btn.label.setText(lang === "tr" ? "Boşluk" : "Space"); } else if (code === "CAPS") { btn.label.setText(btn.isCaps ? t.caps : t.caps2); } else if (code && code.length === 1) { btn.label.setText(btn.isCaps ? code.toLocaleUpperCase(lang === "tr" ? "tr-TR" : "en-US") : code.toLocaleLowerCase(lang === "tr" ? "tr-TR" : "en-US")); } } } } // Skor tablosu puan satırlarını güncellemek için fonksiyon function updateScoreTableRowsLang() { var lang = getLanguage(); var t = (typeof LANGS === "undefined" ? "undefined" : _typeof5(LANGS)) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; // Puan tablosu satırlarını güncelle if (window._farkleScoreTable && window._farkleScoreTable.children) { // Sıralama: satır1a, satır1b, satır2a, satır2b, ... var texts = [[t.mainScore + ": 100", t.mainScore + ": 1000"], [t.mainScore + ": 50", t.mainScore + ": 200"], [t.mainScore + ": 500", t.mainScore + ": 300"], [t.mainScore + ": 750", t.mainScore + ": 400"], [t.mainScore + ": 1500", t.mainScore + ": 500"], [t.mainScore + ": " + (lang === "tr" ? "Joker" : "Joker"), t.mainScore + ": 600"]]; var idx = 0; for (var i = 0; i < texts.length; i++) { for (var j = 0; j < 2; j++) { var row = window._farkleScoreTable.children[idx]; if (row && row.children && row.children.length > 0) { for (var k = 0; k < row.children.length; k++) { var ch = row.children[k]; if (ch instanceof Text2 && ch.size && ch.size < 100) { ch.setText(texts[i][j]); } } } idx++; } } } // Alt açıklama if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.setText(t.info); } } // İflas yazılarını güncellemek için fonksiyon function updateBustTexts() { var lang = getLanguage(); var t = (typeof LANGS === "undefined" ? "undefined" : _typeof5(LANGS)) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; // Oyun ekranında iflas yazısı if (game && game.children) { for (var i = 0; i < game.children.length; i++) { var ch = game.children[i]; if (ch instanceof Text2 && (ch.text === "İflas!" || ch.text === "Bust!")) { ch.setText(t.bust); } } } // Oyun sonu ekranında iflas yazısı if (typeof gameOverContainer !== "undefined" && gameOverContainer && gameOverContainer.children) { for (var i = 0; i < gameOverContainer.children.length; i++) { var ch = gameOverContainer.children[i]; if (ch instanceof Text2 && (ch.text === "İflas!" || ch.text === "Bust!")) { ch.setText(t.bust); } } } } // updateAllTexts fonksiyonunu override et, tüm metinleri ve klavyeleri günceller function updateAllTexts() { var lang = getLanguage(); var t = (typeof LANGS === "undefined" ? "undefined" : _typeof5(LANGS)) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; // Ana Menü if (typeof startTxt !== "undefined") { startTxt.setText(t.start); } if (typeof sifirlaTxt !== "undefined") { sifirlaTxt.setText(t.reset); } if (typeof langTxt !== "undefined") { langTxt.setText(t.lang); } // Diller penceresi açıksa başlık ve butonlar updateLangDialogTexts(); // Skor tablosu ve üst yazılar if (scoreTableRows && scoreTableRows[0]) { var playerNameDisplay = typeof playerName === "string" && playerName.length > 0 ? playerName : lang === "tr" ? "1. Oyuncu" : "Player 1"; scoreTableRows[0].setText(playerNameDisplay + " | " + t.target + " | " + t.ai); } if (scoreTableRows && scoreTableRows[1]) { var dynamicTarget = 1000 + ((typeof storage.level === "number" ? storage.level : 1) - 1) * 250; scoreTableRows[1].setText(t.mainScore + ": " + scores[PLAYER] + " | " + dynamicTarget + " | " + t.mainScore + ": " + scores[NPC]); } if (scoreTableRows && scoreTableRows[2]) { scoreTableRows[2].setText(t.tempScore + ": " + tempScores[PLAYER] + " | " + (lang === "tr" ? "Tur" : "Turn") + ": " + turnNumber + " | " + t.tempScore + ": " + tempScores[NPC]); } if (scoreTableRows && scoreTableRows[3]) { var liveSelectedScorePlayer = 0; var liveSelectedScoreNPC = 0; if (current === PLAYER && selectedDiceIdx.length > 0) { var selValsLive = selectedDiceIdx.map(function (i) { return dice[i].value; }); if (isValidSelection(selValsLive)) { liveSelectedScorePlayer = calcScoreFarkle(selValsLive).score; } } if (current === NPC && dice.length > 0) { var selValsLiveNPC = []; for (var i = 0; i < dice.length; i++) { if (dice[i].selected) { selValsLiveNPC.push(dice[i].value); } } if (selValsLiveNPC.length > 0 && isValidSelection(selValsLiveNPC)) { liveSelectedScoreNPC = calcScoreFarkle(selValsLiveNPC).score; } } scoreTableRows[3].setText(t.selectedScore + ": " + (current === PLAYER ? liveSelectedScorePlayer : selectedScores[PLAYER]) + " | " + (lang === "tr" ? "Seçilen" : "Selected") + " | " + t.selectedScore + ": " + (current === NPC ? liveSelectedScoreNPC : selectedScores[NPC])); } if (typeof turnTxt !== "undefined") { turnTxt.setText(current === PLAYER ? t.turn1 : t.turn2); } // Zar istatistik satırı, info yazısı if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.setText(t.info); } // Oyun sonu ekranı if (typeof gameOverContainer !== "undefined" && gameOverContainer && gameOverContainer.children) { for (var i = 0; i < gameOverContainer.children.length; i++) { var ch = gameOverContainer.children[i]; if (ch instanceof Text2 && (ch.size === 200 || ch.size === 180)) { if (current === PLAYER) { ch.setText(t.win); } else if (current === NPC) { ch.setText(t.lose); } } if (ch instanceof Container && ch.children && ch.children.length > 0) { for (var j = 0; j < ch.children.length; j++) { var sub = ch.children[j]; if (sub instanceof Text2 && sub.text && (sub.text === "Ana Menüye Dön" || sub.text === "Return to Menu")) { sub.setText(t.menu); } } } } } // Ana menüdeki menü butonları if (typeof menuTxt !== "undefined") { menuTxt.setText(t.menu); } // Butonlar (oyun ekranı) if (typeof passTxt !== "undefined") { passTxt.setText(t.pass); } if (typeof rollTxt !== "undefined") { rollTxt.setText(t["continue"]); } if (typeof bankTxt !== "undefined") { bankTxt.setText(t.bank); } // Win rate, maç sayısı, seviye if (window.winRateTxt) { var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0; var winGames = typeof storage.winGames === "number" ? storage.winGames : 0; var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1; var oran = totalGames > 0 ? Math.round(winGames / totalGames * 100) + "%" : lang === "tr" ? "∅" : "∅"; var oyunStr = totalGames > 0 ? totalGames : "0"; window.winRateTxt.setText(t.winRate + ": " + oran + " | " + t.matchCount + ": " + oyunStr + " | " + t.level + ": " + level); } // Instagram ve erken erişim if (window.instaText) { window.instaText.setText(t.instagram); } if (window.betaText) { window.betaText.setText(t.earlyAccess); } // Yükleme ekranı if (typeof loadingContainer !== "undefined" && loadingContainer && loadingContainer.children) { for (var i = 0; i < loadingContainer.children.length; i++) { var ch = loadingContainer.children[i]; if (ch instanceof Text2 && ch.size === 90) { ch.setText(t.loading); } if (ch instanceof Text2 && ch.size === 36) { ch.setText(t.loadingInfo); } } } // Skor tablosu puan satırları updateScoreTableRowsLang(); // Klavye tuşları (oyuncu adı ve reset dialogları) if (typeof playerNameDialog !== "undefined" && playerNameDialog) { updateKeyboardLabels(playerNameDialog, "playerName"); } if (typeof resetInput !== "undefined" && playerNameDialog) { updateKeyboardLabels(playerNameDialog, "reset"); } // İflas yazısı updateBustTexts(); } // updateLangDialogTexts fonksiyonunu da güncel tut function updateLangDialogTexts() { if (!langDialog) { return; } var lang = getLanguage(); var t = (typeof LANGS === "undefined" ? "undefined" : _typeof5(LANGS)) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; for (var i = 0; i < langDialog.children.length; i++) { var ch = langDialog.children[i]; if (ch instanceof Text2) { ch.setText(t.langTitle); } if (ch instanceof Container && ch.children && ch.children.length > 0) { for (var j = 0; j < ch.children.length; j++) { var sub = ch.children[j]; if (sub instanceof Text2) { if (sub.text === "Türkçe" || sub.text === "Turkish") { sub.setText(t.turkce); } if (sub.text === "English") { sub.setText(t.ingilizce); } } } } } } // updateHUD fonksiyonu (orijinal) function updateHUD() { // --- Buton aktifliği --- var selVals = selectedDiceIdx.map(function (i) { return dice[i].value; }); var valid = isValidSelection(selVals); rollBtn.alpha = bankBtn.alpha = valid ? 1 : 0.4; rollBtn.interactive = bankBtn.interactive = valid && current === PLAYER && !gameOver; // --- Skor tablosu ilk kez oluşturuluyorsa ekle --- if (!scoreTableRows[0]) { // Lig: 10 oyun öncesi derecesiz, sonrası oran aralığına göre var getLeagueAsset = function getLeagueAsset(totalGames, winGames) { if (totalGames < 10) { return "derecesizLigi"; } var rate = totalGames > 0 ? Math.round(winGames / totalGames * 100) : 0; if (rate <= 10) { return "demirLigi"; } if (rate <= 20) { return "bronzLigi"; } if (rate <= 30) { return "gumusLigi"; } if (rate <= 40) { return "altinLigi"; } if (rate <= 50) { return "zumrutLigi"; } if (rate <= 60) { return "platinLigi"; } if (rate <= 70) { return "elmasLigi"; } if (rate <= 80) { return "ustaLigi"; } if (rate <= 90) { return "ustadLigi"; } return "sampiyonlukLigi"; }; // --- Zar kombinasyonları ve puan tablosu --- // Zar assetlerini göstermek için fonksiyon var createDiceRow = function createDiceRow(diceArr, text, size, gap) { var row = new Container(); var x = 0; for (var i = 0; i < diceArr.length; i++) { var asset = LK.getAsset(diceArr[i], { anchorX: 0.5, anchorY: 0.5, width: size, height: size }); asset.x = x; asset.y = 0; row.addChild(asset); x += size + (gap || 10); } if (text) { var txt = new Text2(text, { size: size * 0.6, fill: '#fff' }); txt.anchor.set(0, 0.5); txt.x = x - 25; txt.y = 0; row.addChild(txt); } return row; }; // Tabloyu oluştur // --- Kazanma oranı, seviye, hedef ve lig göstergesi --- // storage'dan toplam oyun ve kazanılan oyun sayısını al var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0; var winGames = typeof storage.winGames === "number" ? storage.winGames : 0; // Seviye: Her kazanılan oyun için 1 artar, başlangıç 1 if (typeof storage.level !== "number" || storage.level < 1) { storage.level = 1; } var level = storage.level; // Hedef: Başlangıç 1000, her seviye +250 if (typeof level !== "number" || level < 1) { level = 1; } var dynamicTarget = 1000 + (level - 1) * 250; var leagueAssetId = getLeagueAsset(totalGames, winGames); // Lig görseli ekle/güncelle if (!window.leagueBadge) { window.leagueBadge = LK.getAsset(leagueAssetId, { anchorX: 0.5, anchorY: 0 }); LK.gui.top.addChild(window.leagueBadge); // Skor tablosunun sağında, ortalanmış şekilde konumlandır window.leagueBadge.x = 575; window.leagueBadge.y = 80; } else { // Sadece asset değişirse güncelle if (window.leagueBadge._assetId !== leagueAssetId) { var parent = window.leagueBadge.parent; var idx = parent ? parent.getChildIndex(window.leagueBadge) : -1; window.leagueBadge.destroy(); window.leagueBadge = LK.getAsset(leagueAssetId, { anchorX: 0.5, anchorY: 0 }); if (parent && idx >= 0) { parent.addChildAt(window.leagueBadge, idx); } window.leagueBadge.x = 575; window.leagueBadge.y = 80; } } window.leagueBadge._assetId = leagueAssetId; // --- Kazanma oranı ve oyun sayısı yazısı --- // Başlangıçta oran yoksa "∅", oyun sayısı yoksa "0" if (!window.winRateTxt) { window.winRateTxt = new Text2("", { size: 48, fill: '#ffe066', fontWeight: 'bold' }); window.winRateTxt.anchor.set(0.5, 0); LK.gui.top.addChild(window.winRateTxt); } var winRateStr = totalGames > 0 ? lang === "tr" ? Math.round(winGames / totalGames * 100) + "%" : Math.round(winGames / totalGames * 100) + "%" : lang === "tr" ? "∅" : "∅"; var oyunSayisiStr = totalGames > 0 ? totalGames : "0"; if (t && t.winRate && t.matchCount && t.level) { window.winRateTxt.setText(t.winRate + ": " + winRateStr + " | " + t.matchCount + ": " + oyunSayisiStr + " | " + t.level + ": " + level); } else { window.winRateTxt.setText("Zafer Oranı: " + winRateStr + " | Maç Sayısı: " + oyunSayisiStr + " | Seviye: " + level); } window.winRateTxt.x = 0; window.winRateTxt.y = 20; // 1. satır: başlıklar var playerNameDisplay = typeof playerName === "string" && playerName.length > 0 ? playerName : "1. Oyuncu"; scoreTableRows[0] = new Text2(playerNameDisplay + " | Hedef | Yapay Zeka", { size: 54, fill: '#007fff', fontWeight: 'bold' }); scoreTableRows[0].anchor.set(0.5, 0); LK.gui.top.addChild(scoreTableRows[0]); // Skor tablosunu ekranın tam ortasına yerleştir // Tüm satırları ve sıra göstergesini tam ekranın ortasına hizala var centerX = 0; scoreTableRows[0].x = centerX; scoreTableRows[0].y = 80; // 2. satır: ana skorlar ve hedef scoreTableRows[1] = new Text2("", { size: 54, fill: '#fff' }); scoreTableRows[1].anchor.set(0.5, 0); LK.gui.top.addChild(scoreTableRows[1]); scoreTableRows[1].x = centerX; scoreTableRows[1].y = scoreTableRows[0].y + 60; // 3. satır: geçici skorlar ve tur scoreTableRows[2] = new Text2("", { size: 48, fill: '#ffe066' }); scoreTableRows[2].anchor.set(0.5, 0); LK.gui.top.addChild(scoreTableRows[2]); scoreTableRows[2].x = centerX; scoreTableRows[2].y = scoreTableRows[1].y + 54; // 4. satır: seçilen skorlar scoreTableRows[3] = new Text2("", { size: 44, fill: '#b3e6ff' }); scoreTableRows[3].anchor.set(0.5, 0); LK.gui.top.addChild(scoreTableRows[3]); scoreTableRows[3].x = centerX; scoreTableRows[3].y = scoreTableRows[2].y + 48; // Sıra göstergesi turnTxt = new Text2('', { size: 54, fill: '#ffe066', fontWeight: 'bold' }); turnTxt.anchor.set(0.5, 0); LK.gui.top.addChild(turnTxt); turnTxt.x = centerX; turnTxt.y = scoreTableRows[3].y + 60; var scoreTableContainer = new Container(); scoreTableContainer.x = 0; scoreTableContainer.y = turnTxt.y + 90; var rowY = 0; var rowGap = 70; var diceSize = 60; var bigGap = 80; // 1. satır var row1a = createDiceRow(['zar1'], "= 100", diceSize); var row1b = createDiceRow(['zar1', 'zar1', 'zar1'], "= 1000", diceSize); row1a.x = -400; row1b.x = 200; row1a.y = row1b.y = rowY + 10; scoreTableContainer.addChild(row1a); scoreTableContainer.addChild(row1b); rowY += rowGap; // 2. satır var row2a = createDiceRow(['zar5'], "= 50", diceSize); var row2b = createDiceRow(['zar2', 'zar2', 'zar2'], "= 200", diceSize); row2a.x = -400; row2b.x = 200; row2a.y = row2b.y = rowY + 10; scoreTableContainer.addChild(row2a); scoreTableContainer.addChild(row2b); rowY += rowGap; // 3. satır var row3a = createDiceRow(['zar1', 'zar2', 'zar3', 'zar4', 'zar5'], "= 500", diceSize); var row3b = createDiceRow(['zar3', 'zar3', 'zar3'], "= 300", diceSize); row3a.x = -400; row3b.x = 200; row3a.y = row3b.y = rowY + 10; ; scoreTableContainer.addChild(row3a); scoreTableContainer.addChild(row3b); rowY += rowGap; // 4. satır var row4a = createDiceRow(['zar2', 'zar3', 'zar4', 'zar5', 'zar6'], "= 750", diceSize); var row4b = createDiceRow(['zar4', 'zar4', 'zar4'], "= 400", diceSize); row4a.x = -400; row4b.x = 200; row4a.y = row4b.y = rowY + 10; ; scoreTableContainer.addChild(row4a); scoreTableContainer.addChild(row4b); rowY += rowGap; // 5. satır var row5a = createDiceRow(['zar1', 'zar2', 'zar3', 'zar4', 'zar5', 'zar6'], "= 1500", diceSize); var row5b = createDiceRow(['zar5', 'zar5', 'zar5'], "= 500", diceSize); row5a.x = -400; row5b.x = 200; row5a.y = row5b.y = rowY + 10; ; scoreTableContainer.addChild(row5a); scoreTableContainer.addChild(row5b); rowY += rowGap; // 6. satır var row6a = createDiceRow(['zarJoker'], "= Joker", diceSize); var row6b = createDiceRow(['zar6', 'zar6', 'zar6'], "= 600", diceSize); row6a.x = -400; row6b.x = 200; row6a.y = row6b.y = rowY + 10; ; scoreTableContainer.addChild(row6a); scoreTableContainer.addChild(row6b); rowY += rowGap; // Ortala scoreTableContainer.x = 0; scoreTableContainer.y = turnTxt.y + 90; scoreTableContainer.pivot.x = 0; scoreTableContainer.pivot.y = 0; scoreTableContainer.anchorX = 0.5; scoreTableContainer.anchorY = 0; scoreTableContainer.x = 0; // GUI'ye ekle (top bölgesine, skor tablosunun altına) LK.gui.top.addChild(scoreTableContainer); scoreTableContainer.x = 0; scoreTableContainer.y = turnTxt.y + 90; // Altına gri açıklama yazısı ekle if (!window._farkleScoreInfoTxt) { var lang = getLanguage(); var infoText = typeof LANGS !== "undefined" && LANGS && LANGS[lang] && LANGS[lang].info ? LANGS[lang].info : "3'ten sonraki her ilave zar değerini iki katına çıkarır."; var infoTxt = new Text2(infoText, { size: 38, fill: '#b0b0b0' }); infoTxt.anchor.set(0.5, 0); infoTxt.x = 0; infoTxt.y = scoreTableContainer.y + scoreTableContainer.height; LK.gui.top.addChild(infoTxt); window._farkleScoreInfoTxt = infoTxt; } else { // Her update'te pozisyonunu güncelle window._farkleScoreInfoTxt.x = 0; window._farkleScoreInfoTxt.y = scoreTableContainer.y + scoreTableContainer.height + 20; // Her update'te metni güncelle var lang = getLanguage(); var infoText = typeof LANGS !== "undefined" && LANGS && LANGS[lang] && LANGS[lang].info ? LANGS[lang].info : "3'ten sonraki her ilave zar değerini iki katına çıkarır."; window._farkleScoreInfoTxt.setText(infoText); } // Tablonun referansını sakla (gerekirse erişmek için) window._farkleScoreTable = scoreTableContainer; } // --- Skor tablosunu güncelle --- // Her zaman güncel dynamicTarget'ı göster // --- DİL DESTEKLİ: Skor tablosu ve üst yazılar --- var lang = getLanguage(); var t = (typeof LANGS === "undefined" ? "undefined" : _typeof5(LANGS)) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; if (scoreTableRows && scoreTableRows[0]) { var playerNameDisplay = typeof playerName === "string" && playerName.length > 0 ? playerName : lang === "tr" ? "1. Oyuncu" : "Player 1"; scoreTableRows[0].setText(playerNameDisplay + " | " + (t.target || "Hedef") + " | " + (t.ai || "Yapay Zeka")); } if (scoreTableRows && scoreTableRows[1]) { var dynamicTarget = 1000 + ((typeof storage.level === "number" ? storage.level : 1) - 1) * 250; scoreTableRows[1].setText((t.mainScore || "Ana Skor") + ": " + scores[PLAYER] + " | " + dynamicTarget + " | " + (t.mainScore || "Ana Skor") + ": " + scores[NPC]); } if (scoreTableRows && scoreTableRows[2]) { scoreTableRows[2].setText((t.tempScore || "Geçici Skor") + ": " + tempScores[PLAYER] + " | " + (lang === "tr" ? "Tur" : "Turn") + ": " + turnNumber + " | " + (t.tempScore || "Geçici Skor") + ": " + tempScores[NPC]); } if (scoreTableRows && scoreTableRows[3]) { var liveSelectedScorePlayer = 0; var liveSelectedScoreNPC = 0; if (current === PLAYER && selectedDiceIdx.length > 0) { var selValsLive = selectedDiceIdx.map(function (i) { return dice[i].value; }); if (isValidSelection(selValsLive)) { liveSelectedScorePlayer = calcScoreFarkle(selValsLive).score; } } if (current === NPC && dice.length > 0) { var selValsLiveNPC = []; for (var i = 0; i < dice.length; i++) { if (dice[i].selected) { selValsLiveNPC.push(dice[i].value); } } if (selValsLiveNPC.length > 0 && isValidSelection(selValsLiveNPC)) { liveSelectedScoreNPC = calcScoreFarkle(selValsLiveNPC).score; } } scoreTableRows[3].setText((t.selectedScore || "Seçilen Skor") + ": " + (current === PLAYER ? liveSelectedScorePlayer : selectedScores[PLAYER]) + " | " + (lang === "tr" ? "Seçilen" : "Selected") + " | " + (t.selectedScore || "Seçilen Skor") + ": " + (current === NPC ? liveSelectedScoreNPC : selectedScores[NPC])); } if (typeof turnTxt !== "undefined") { turnTxt.setText(current === PLAYER ? t.turn1 || "Sıra: 1. Oyuncuda" : t.turn2 || "Sıra: 2. Oyuncuda"); } // Zar istatistik satırı, info yazısı if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.setText(t.info || "3'ten sonraki her ilave zar değerini iki katına çıkarır."); } } // --- Zar istatistikleri: her oyuncuya gelen zarların adedi --- // storage'da saklanacak anahtarlar: zarStats = { zar1: 0, zar2: 0, ... } var diceStatKeys = ['zar2', 'zar3', 'zar4', 'zar5', 'zar6', 'zar1', 'zarJoker']; var defaultZarStats = { zar1: 0, zar2: 0, zar3: 0, zar4: 0, zar5: 0, zar6: 0, zarJoker: 0 }; if (_typeof3(storage.zarStats) !== "object" || !storage.zarStats) { storage.zarStats = Object.assign({}, defaultZarStats); } var zarStats = storage.zarStats; // --- Zar istatistiklerini güncelleyen fonksiyon --- // Bu fonksiyon, oyuncuya yeni zarlar geldiğinde çağrılmalı function updateZarStatsForPlayerDice(diceArr) { var changed = false; for (var i = 0; i < diceArr.length; i++) { var v = diceArr[i]; var key = "zar" + v; if (key === "zar0" || key === "zarundefined" || key === "zarNaN") { continue; } if (zarStats.hasOwnProperty(key)) { zarStats[key]++; changed = true; } } // Joker zarları da say (ör: value==7 veya value==0 ise zarJoker) for (var i = 0; i < diceArr.length; i++) { if (diceArr[i] === 0 || diceArr[i] === 7) { zarStats["zarJoker"]++; changed = true; } } if (changed) { storage.zarStats = zarStats; } } // --- Zar istatistiklerini gösteren görsel satır (dice assetleri + sayı) --- // Sadece bir kez oluşturulacak, sonra güncellenecek if (!window.zarStatsRow) { // Ana container var statsRow = new Container(); // Sıralama: zar2, zar3, zar4, zar5, zar6, zar1, zarJoker var diceKeys = diceStatKeys; var diceSize = 100; var gap = 20; var totalWidth = diceKeys.length * diceSize + (diceKeys.length - 1) * gap; var startX = -totalWidth / 2 + diceSize / 2; statsRow.diceAssets = []; statsRow.countTexts = []; for (var i = 0; i < diceKeys.length; i++) { var key = diceKeys[i]; // Zar görseli var asset = LK.getAsset(key, { anchorX: 0.5, anchorY: 1, width: diceSize, height: diceSize }); asset.x = startX + i * (diceSize + gap); asset.y = 0; statsRow.addChild(asset); statsRow.diceAssets.push(asset); // Altına sayı var count = zarStats[key] || 0; var countTxt = new Text2(count + "", { size: 36, fill: 0xFFE066, fontWeight: "bold" }); countTxt.anchor.set(0.5, 0); countTxt.x = asset.x; countTxt.y = 8; statsRow.addChild(countTxt); statsRow.countTexts.push(countTxt); } // 'tutVeTuruSonlandirButonuGorseli' assetinin biraz üstünde olacak şekilde konumlandır statsRow.x = bankBtn.x; statsRow.y = bankBtn.y - 200; LK.gui.bottom.addChild(statsRow); window.zarStatsRow = statsRow; } // --- Zar istatistiklerini güncelleyen fonksiyon (görsel) --- function refreshZarStatsTxt() { // Sıralama: zar2, zar3, zar4, zar5, zar6, zar1, zarJoker if (!window.zarStatsRow) { return; } for (var i = 0; i < diceStatKeys.length; i++) { var key = diceStatKeys[i]; var val = zarStats[key] || 0; if (window.zarStatsRow.countTexts[i]) { window.zarStatsRow.countTexts[i].setText(val + ""); } } } // --- Oyun başında ve her zar atışında güncelle refreshZarStatsTxt(); /**** --- Tur Aksiyonları --- */ function rollAll() { if (gameOver || current !== PLAYER) { return; } dice.forEach(function (d) { if (!d.selected) { var v = randomDiceValue(); d.setValue(v); // Joker gelirse 0 olarak kalacak } }); // --- Zar istatistiklerini güncelle (sadece oyuncu için) --- if (current === PLAYER) { var playerDiceVals = dice.filter(function (d) { return !d.selected; }).map(function (d) { return d.value; }); updateZarStatsForPlayerDice(playerDiceVals); refreshZarStatsTxt(); } updateDicePositions(); updateHUD(); saveGameState(); // Zar atınca kaydet var unselVals = dice.filter(function (d) { return !d.selected; }).map(function (d) { return d.value; }); // Eğer oyuncu zar attıktan sonra hiçbir şekilde kombinasyon yapılamıyorsa otomatik olarak turu rakibe geçir if (!canMakeAnyScore(unselVals)) { // Kırmızı ekranı daha uzun göster (ör: 1200ms) LK.effects.flashScreen(0xff0000, 1200); // "İflas!" yazısı ekle var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!"; var iflasTxt = new Text2(bustText, { size: 180, fill: '#fff' }); iflasTxt.anchor.set(0.5, 0.5); iflasTxt.x = W / 2; iflasTxt.y = H / 2; iflasTxt.alpha = 1; game.addChild(iflasTxt); // İflas sesi (ben) var iflasBenSesi = LK.getSound && LK.getSound('iflasBenSesi'); if (iflasBenSesi && iflasBenSesi.play) { iflasBenSesi.play(); } // 1 saniye boyunca göster, sonra yavaşça kaybolsun LK.setTimeout(function () { tween(iflasTxt, { alpha: 0 }, { duration: 700, easing: tween.easeOut, onFinish: function onFinish() { if (iflasTxt && iflasTxt.parent) { iflasTxt.parent.removeChild(iflasTxt); } tempScores[current] = 0; selectedScores[current] = 0; turnScore = 0; updateHUD(); LK.setTimeout(endTurn, BUST_PASS_DELAY); } }); }, 1000); } } function keepAndContinue() { if (gameOver || current !== PLAYER) { return; } var selVals = selectedDiceIdx.map(function (i) { return dice[i].value; }); if (!isValidSelection(selVals)) { return; } // Seçilen skor hesapla ve ekle var selScore = calcScoreFarkle(selVals).score; selectedScores[current] = selScore; tempScores[current] += selectedScores[current]; selectedScores[current] = 0; // Seçilen skor sıfırlanır // turnScore artık kullanılmıyor, backward compatibility için güncelle turnScore = tempScores[current]; // Seçili zarları kaldır dice = dice.filter(function (d, i) { return !selectedDiceIdx.includes(i); }).map(function (d) { return d; }); selectedDiceIdx = []; if (dice.length === 0) { handleHotDice(function () { // oyuncu ise hiçbir şey yapma / NPC ise npcQuickDecision }); return; // alttaki akışı atla } else { dice.forEach(function (d) { d.selected = false; // sadece seçimi temizle }); renumberDice(); updateDicePositions(); } updateHUD(); saveGameState(); // Devam et seçeneğinde kaydet var unselVals = dice.map(function (d) { return d.value; }); // Eğer kalan zarlarla hiçbir şekilde kombinasyon yapılamıyorsa otomatik olarak turu rakibe geçir if (!canMakeAnyScore(unselVals)) { LK.effects.flashScreen(0xff0000, 1200); var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!"; var iflasTxt = new Text2(bustText, { size: 180, fill: '#fff' }); iflasTxt.anchor.set(0.5, 0.5); iflasTxt.x = W / 2; iflasTxt.y = H / 2; iflasTxt.alpha = 1; game.addChild(iflasTxt); // İflas sesi (ben) var iflasBenSesi = LK.getSound && LK.getSound('iflasBenSesi'); if (iflasBenSesi && iflasBenSesi.play) { iflasBenSesi.play(); } LK.setTimeout(function () { tween(iflasTxt, { alpha: 0 }, { duration: 700, easing: tween.easeOut, onFinish: function onFinish() { if (iflasTxt && iflasTxt.parent) { iflasTxt.parent.removeChild(iflasTxt); } tempScores[current] = 0; selectedScores[current] = 0; turnScore = 0; updateHUD(); LK.setTimeout(endTurn, BUST_PASS_DELAY); } }); }, 1000); } } function keepAndEndTurn() { if (gameOver || current !== PLAYER) { return; } var selVals = selectedDiceIdx.map(function (i) { return dice[i].value; }); if (!isValidSelection(selVals)) { return; } // Seçilen skor hesapla ve ekle var selScore = calcScoreFarkle(selVals).score; selectedScores[current] = selScore; // Ana skora ekle: geçici skor + seçilen skor scores[current] += tempScores[current] + selectedScores[current]; // Sıfırla tempScores[current] = 0; selectedScores[current] = 0; turnScore = 0; updateHUD(); saveGameState(); // Tur sonlandırınca kaydet // --- Zar istatistiklerini güncelle (tur sonunda kalan zarlar) --- if (current === PLAYER) { var playerDiceVals = []; for (var i = 0; i < dice.length; i++) { playerDiceVals.push(dice[i].value); } updateZarStatsForPlayerDice(playerDiceVals); refreshZarStatsTxt(); } endTurn(); } function endTurn() { // Kazanan kontrolü // Hedefi dinamik olarak hesapla (her seviye için 1000 + (level-1)*250) var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1; var dynamicTarget = 1000 + (level - 1) * 250; // Oyunculardan herhangi biri hedefe ulaştıysa oyunu bitir if (scores[PLAYER] >= dynamicTarget || scores[NPC] >= dynamicTarget) { // Kazananı belirle: önce bitiren kazanır if (scores[PLAYER] >= dynamicTarget && scores[NPC] >= dynamicTarget) { // Beraberlik durumunda önceki current kazansın showWinner(); } else if (scores[PLAYER] >= dynamicTarget) { current = PLAYER; showWinner(); } else { current = NPC; showWinner(); } return; } // Sırayı değiştir var prevCurrent = current; current = current === PLAYER ? NPC : PLAYER; // Sıra değişiminde uygun sesi çal if (prevCurrent === PLAYER && current === NPC) { var rakibinSirasiSesi = LK.getSound && LK.getSound('rakibinSirasiSesi'); if (rakibinSirasiSesi && rakibinSirasiSesi.play) { rakibinSirasiSesi.play(); } } else if (prevCurrent === NPC && current === PLAYER) { var siraSendeSesi = LK.getSound && LK.getSound('siraSendeSesi'); if (siraSendeSesi && siraSendeSesi.play) { siraSendeSesi.play(); } } // Yeni oyuncunun geçici ve seçilen skorlarını sıfırla tempScores[current] = 0; selectedScores[current] = 0; turnScore = 0; // Tur sayısını sadece 1. oyuncuya geçerken artır if (current === PLAYER) { turnNumber++; } resetDice(6, current === PLAYER); updateHUD(); saveGameState(); // Sıra değişince kaydet // --- HATA DÜZELTME: Zarlar otomatik atıldığında hiçbir kombinasyon yapılamıyorsa otomatik iflas ve sıra geçişi --- // Sadece yeni tur başında, zarlar atıldıktan hemen sonra kontrol et var unselVals = dice.map(function (d) { return d.value; }); if (!canMakeAnyScore(unselVals)) { // Ekranı kırmızıya flash et LK.effects.flashScreen(0xff0000, 1200); // "İflas!" yazısı ekle var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!"; var iflasTxt = new Text2(bustText, { size: 180, fill: '#fff' }); iflasTxt.anchor.set(0.5, 0.5); iflasTxt.x = W / 2; iflasTxt.y = H / 2; iflasTxt.alpha = 1; game.addChild(iflasTxt); // Sesi çal (oyuncuya ve sıra geçişine göre) var iflasSesi = null; if (prevCurrent === PLAYER && current === NPC) { // 1. oyuncudan 2. oyuncuya geçerken iflas: rakip sesi iflasSesi = LK.getSound && LK.getSound('iflasRakipSesi'); } else if (prevCurrent === NPC && current === PLAYER) { // 2. oyuncudan 1. oyuncuya geçerken iflas: ben sesi iflasSesi = LK.getSound && LK.getSound('iflasBenSesi'); } if (iflasSesi && iflasSesi.play) { iflasSesi.play(); } LK.setTimeout(function () { tween(iflasTxt, { alpha: 0 }, { duration: 700, easing: tween.easeOut, onFinish: function onFinish() { if (iflasTxt && iflasTxt.parent) { iflasTxt.parent.removeChild(iflasTxt); } tempScores[current] = 0; selectedScores[current] = 0; turnScore = 0; updateHUD(); // Sırayı tekrar değiştir (sonsuz döngüye girmemesi için current bir kez daha değişecek) // Not: endTurn fonksiyonu tekrar çağrılırsa, bir sonraki oyuncuya geçer LK.setTimeout(endTurn, BUST_PASS_DELAY); } }); }, 1000); return; // Diğer kodları çalıştırma } if (current === NPC) { npcTurn(); // aynen kalsın } else { // animasyon bittikten sonra iflas kontrolü yap animateRoll(function () { var vals = dice.map(function (d) { return d.value; }); if (!canMakeAnyScore(vals)) { if (current === PLAYER) { playerBustFlow(); // ← senin iflasın } else { npcBustFlow(); // ← NPC iflası } } }); } } /* --- NPC Basit AI --- */ // ► Kurallı AI’da kullanılacak geçici alan var bestMove = null; var bestMoveBank = false; function npcTurn() { // Oyunun bittiğini veya sıranın NPC’de olmadığını kontrol et if (gameOver || current !== NPC) { return; } /* Önce tüm zarları seçimsiz hâle getir ve güncelle */ var _iterator3 = _createForOfIteratorHelper2(dice), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var d = _step3.value; d.selected = false; } } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } updateDicePositions(); animateRoll(function () { /* Zarlar durduktan sonra 1 sn bekle */ LK.setTimeout(function () { // — reset — bestMove = null; bestMoveBank = false; bestMoveScore = -Infinity; LK.setTimeout(npcQuickDecision, NPC_STEP_DELAY); // <- 1 sn sonra }, NPC_STEP_DELAY); // NPC_STEP_DELAY = 1000 }); } /** * Zar sayısına göre tablolaştırılmış kurallarla * - hangi zarı seçeceğine * - banklayıp banklamayacağına * karar verir ve applyFinalDecision’ı tetikler. */ function npcQuickDecision() { /* 0) Seçim bayraklarını sıfırla ─ animasyon hatalarını önler */ dice.forEach(function (d) { return d.selected = false; }); updateDicePositions(); // 0.a) Zar değerlerini oku var vals = dice.map(function (d) { return d.value; }); var n = vals.length; /* === 0.a) HOT-DICE kontrolü (öncelik) === */ var fullScore = calcScoreFarkle(vals); var hotDice = fullScore.score > 0 && fullScore.used.length === vals.length; if (hotDice) { /* Zarları ŞİMDİ seçme — sadece kararı kaydet */ bestMove = { combo: vals.slice(), score: fullScore.score }; bestMoveBank = false; // DEVAM /* return yok! En alttaki “seçme bloğuna” akmaya devam edeceğiz */ } /* Tek-zar‐devam ve banklama mantığına yalnızca hot-dice DEĞİLSE bak */ if (!hotDice) { // ==== 1) Tek–zar DEVAM listesi ==== var sig = vals.slice().sort(function (a, b) { return a - b; }).filter(function (v) { return v === 1 || v === 5; }).join(''); var singleContinue = (CONTINUE_PATTERNS[n] || []).includes(sig); /* ---------- YENİ EK ---------- */ var BANK_THRESHOLD = 400; // dilediğin rakam var counts = Array(7).fill(0); vals.forEach(function (v) { return counts[v]++; }); var hasTripleOrBetter = counts.some(function (c) { return c >= 3; }); // 2-2-2 gibi // Elin puanı düşükse banklamak istemiyoruz var best = bestScoringCombo(vals); // {combo, score} var worthBanking = hasTripleOrBetter || best.score >= BANK_THRESHOLD; // Liste kuralı devrede ama banklamaya değer bir durum varsa if (singleContinue && worthBanking) { singleContinue = false; // → else bloğuna gitsin } /* ---------- /YENİ EK ---------- */ if (singleContinue) { // sadece 1 ya da 5'ten **birini** tut ve DEVAM et var pickDie = vals.includes(1) ? 1 : 5; bestMove = { combo: [pickDie], score: calcScoreFarkle([pickDie]).score }; bestMoveBank = false; // DEVAM } else { // En iyi kombinasyon + BANK bestMove = best; // az önce zaten hesapladık bestMoveBank = true; // TAMAM } // 2) Kararı uygula if (singleContinue) { // Listede varsa sadece **TEK** zar tutulur var pickDie = vals.includes(1) ? 1 : 5; // 1 öncelikli var idx = vals.indexOf(pickDie); bestMove = { combo: [pickDie], score: calcScoreFarkle([pickDie]).score }; bestMoveBank = false; // DEVAM } else { // En iyi kombinasyon + BANK best = bestScoringCombo(vals); worthBanking = best.score >= 400; // eşiği istediğin gibi ayarla if (singleContinue && worthBanking) { singleContinue = false; // yüksek puan varsa bankla } // hiç puan getiren kombinasyon yoksa iflas if (!best || best.score === 0 || !best.combo.length) { npcBustFlow(); return; } bestMove = best; bestMoveBank = true; // TAMAM } } /* Eşik kuralı */ // a) Dinamik hedefi hesapla (oyuncuda kullandığınızla aynı) var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1; var targetScore = 1000 + (level - 1) * 250; // <-- aynı formül // b) NPC’nin bu tur banklarsa ulaşacağı toplam puan var potentialTotal = scores[NPC] // ana skor + tempScores[NPC] // geçici skor + bestMove.score; // yeni seçilen skor // c) Kazanıyorsa ZORUNLU bankla if (potentialTotal >= targetScore) { bestMoveBank = true; } // d) Aksi hâlde eski “≥1000” eşiğini korumak istiyorsanız: else if (tempScores[NPC] + bestMove.score >= 1000) { bestMoveBank = true; } // 3) Görsel güncellemeler + kararın uygulanması updateDicePositions(); updateHUD(); /*********** TEKER TEKER SEÇME BLOĞU ***********/ // Hangi zarlar seçilecek? → npcSelectOrder var npcSelectOrder = []; var valsCopy = vals.slice(); // birazdan -1 ile işaretleyeceğiz bestMove.combo.forEach(function (v) { var i = valsCopy.indexOf(v); if (i !== -1) { npcSelectOrder.push(i); valsCopy[i] = -1; // aynı zarı 2. kez bulma } }); var step = 0; function selectNext() { if (step < npcSelectOrder.length) { var idx = npcSelectOrder[step++]; /* ses efekti */ var sfx = LK.getSound('zarSecmeSesi'); sfx && sfx.play(); dice[idx].selected = true; updateDicePositions(); updateHUD(); /* 1 sn sonra bir sonraki zara geç */ LK.setTimeout(selectNext, NPC_STEP_DELAY); } else { /* Son zarı da seçtik → 1 sn sonra butona bas */ LK.setTimeout(function () { // 1) Buton sesini GECİKME-siz çal var btnSound = bestMoveBank ? 'tutVeTuruSonlandirSesi' // → TAMAM : 'tutVeDevamEtSesi'; // → DEVAM var s = LK.getSound(btnSound); s && s.play(); LK.setTimeout(applyFinalDecision, 0); }, 0); // ilk setTimeout’u 0 ms yap – ses anında gelsin } } /* İlk seçimi başlat */ LK.setTimeout(selectNext, NPC_STEP_DELAY); } /* --- Kazanan ekranı --- */ function showWinner() { gameOver = true; // Kazanma oranı güncellemesi var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0; var winGames = typeof storage.winGames === "number" ? storage.winGames : 0; totalGames += 1; if (current === PLAYER) { winGames += 1; // Seviye artır if (typeof storage.level !== "number" || storage.level < 1) { storage.level = 1; } storage.level += 1; } else { // Kaybedince seviye artmasın, mevcut değeri koru if (typeof storage.level !== "number" || storage.level < 1) { storage.level = 1; } } storage.totalGames = totalGames; storage.winGames = winGames; // Hedefi güncelle (her seviye +250) if (typeof storage.level !== "number" || storage.level < 1) { storage.level = 1; } var level = storage.level; var dynamicTarget = 1000 + (level - 1) * 250; // Lig görselini güncelle function getLeagueAsset(totalGames, winGames) { if (totalGames < 10) { return "derecesizLigi"; } var rate = totalGames > 0 ? Math.round(winGames / totalGames * 100) : 0; if (rate <= 10) { return "demirLigi"; } if (rate <= 20) { return "bronzLigi"; } if (rate <= 30) { return "gumusLigi"; } if (rate <= 40) { return "altinLigi"; } if (rate <= 50) { return "zumrutLigi"; } if (rate <= 60) { return "platinLigi"; } if (rate <= 70) { return "elmasLigi"; } if (rate <= 80) { return "ustaLigi"; } if (rate <= 90) { return "ustadLigi"; } return "sampiyonlukLigi"; } var leagueAssetId = getLeagueAsset(totalGames, winGames); if (window.leagueBadge) { if (window.leagueBadge._assetId !== leagueAssetId) { var parent = window.leagueBadge.parent; var idx = parent ? parent.getChildIndex(window.leagueBadge) : -1; window.leagueBadge.destroy(); window.leagueBadge = LK.getAsset(leagueAssetId, { anchorX: 0.5, anchorY: 0 }); if (parent && idx >= 0) { parent.addChildAt(window.leagueBadge, idx); } window.leagueBadge.x = 575; window.leagueBadge.y = 80; } } if (window.leagueBadge) { window.leagueBadge._assetId = leagueAssetId; } // HUD'daki oranı, oyun sayısı, seviye ve hedefi hemen güncelle if (window.winRateTxt) { var winRateStr = totalGames > 0 ? "%" + Math.round(winGames / totalGames * 100) : "∅"; var oyunSayisiStr = totalGames > 0 ? totalGames : "0"; window.winRateTxt.setText("Zafer Oranı: " + winRateStr + " | Maç Sayısı: " + oyunSayisiStr + " | Seviye: " + level); } if (scoreTableRows && scoreTableRows[1]) { scoreTableRows[1].setText("Ana Skor: " + scores[PLAYER] + " | " + (typeof dynamicTarget === "number" ? dynamicTarget : function () { var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1; return 1000 + (level - 1) * 250; }()) + " | Ana Skor: " + scores[NPC]); } var winnerText = current === PLAYER ? 'Kazandın!' : 'Kaybettin...'; clearGameState(); showGameOverScreen(winnerText); } /* --- Buton Olayları --- */ rollBtn.down = function () { if (gameOver || current !== PLAYER) { return; } // Tüm zarlar seçili (hot-dice) ise önce puanı uygula var hotDice = selectedDiceIdx.length === dice.length; if (hotDice) { // Skoru ekle, yeni 6 zarı hazırla keepAndContinue(); // burada resetDice(6) zaten çağrılıyor } else { var _LK$getSound3; (_LK$getSound3 = LK.getSound('tutVeDevamEtSesi')) === null || _LK$getSound3 === void 0 || _LK$getSound3.play(); animateRoll(keepAndContinue, false); } }; bankBtn.down = function () { if (current === PLAYER) { var tutTuruSonlandirSesi = LK.getSound && LK.getSound('tutVeTuruSonlandirSesi'); if (tutTuruSonlandirSesi && tutTuruSonlandirSesi.play) { tutTuruSonlandirSesi.play(); } keepAndEndTurn(); } }; // PAS GEÇ butonu olayı passBtn.down = function () { if (current === PLAYER && !gameOver) { var pasButonuSesi = LK.getSound && LK.getSound('pasButonuSesi'); if (pasButonuSesi && pasButonuSesi.play) { pasButonuSesi.play(); } // Sıramı pas geç, turu rakibe geçir tempScores[current] = 0; selectedScores[current] = 0; turnScore = 0; updateHUD(); saveGameState(); // Pas geçince kaydet endTurn(); } }; /* --- Başlat --- */ function startGame() { // Try to restore game state if available and not game over if (typeof storage !== "undefined" && storage && storage.tempGameState && storage.tempGameState.gameOver !== true) { if (restoreGameState()) { // Oyun arkaplanını güncelle (restoreGameState'de resetDice çağrıldı, burada tekrar ekle) if (game._oyunBg) { game._oyunBg.destroy(); game._oyunBg = null; } var oyunBg = LK.getAsset('oyunEkraniArkaplani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: W, height: H }); game.addChildAt(oyunBg, 0); game._oyunBg = oyunBg; updateHUD(); var ilkSenBasliyorsunSesi = LK.getSound && LK.getSound('ilkSenBasliyorsunSesi'); if (ilkSenBasliyorsunSesi && ilkSenBasliyorsunSesi.play) { ilkSenBasliyorsunSesi.play(); } // Zar animasyonu oynatma (isteğe bağlı, restore sonrası) animateRoll(); return; } } // Normal yeni oyun başlat scores = [0, 0]; tempScores = [0, 0]; selectedScores = [0, 0]; turnScore = 0; turnNumber = 1; current = NPC; gameOver = false; // Set oyunEkraniArkaplani as background if (game._oyunBg) { game._oyunBg.destroy(); game._oyunBg = null; } var oyunBg = LK.getAsset('oyunEkraniArkaplani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: W, height: H }); game.addChildAt(oyunBg, 0); game._oyunBg = oyunBg; // Müzik sadece loading ekranı kalkınca başlatılacak, burada tekrar başlatılmıyor resetDice(6); updateHUD(); // İlk oyun başlangıcında rakip başlıyorsa özel sesi çal var ilkRakipBasliyorSesi = LK.getSound && LK.getSound('ilkRakipBasliyorSesi'); if (ilkRakipBasliyorSesi && ilkRakipBasliyorSesi.play) { ilkRakipBasliyorSesi.play(); } else { var rakipSesi = LK.getSound && LK.getSound('rakibinSirasiSesi'); rakipSesi && rakipSesi.play(); } npcTurn(); } // --- Ana Menü ve Oyun Sonu Ekranları --- var mainMenuContainer = null; var gameOverContainer = null; // Oyuncu adı global değişkeni var playerName = storage.playerName || null; // Oyuncu adı giriş penceresi için referanslar var playerNameDialog = null; // Hesabı Sıfırla onay penceresi function showResetAccountDialog() { // Önce varsa eski dialog'u kaldır if (playerNameDialog) { playerNameDialog.destroy(); playerNameDialog = null; } playerNameDialog = new Container(); playerNameDialog.width = 900; playerNameDialog.height = 600; playerNameDialog.x = W / 2 - 450; playerNameDialog.y = H / 2 - 300; // Arkaplan kutusu var bg = LK.getAsset('loadingBgRed', { anchorX: 0, anchorY: 0, color: 0x222222 }); playerNameDialog.addChild(bg); // Başlık var info = new Text2("Bu işlemden emin misin?", { size: 54, fill: 0xFFE066 }); info.anchor.set(0.5, 0); info.x = 450; info.y = 60; playerNameDialog.addChild(info); // Input kutusu var resetInput = new Text2("", { size: 80, fill: "#fff", background: "#444", padding: 24 }); resetInput.anchor.set(0.5, 0); resetInput.x = 450; resetInput.y = info.y + 70; resetInput.interactive = true; resetInput.text = ""; playerNameDialog.addChild(resetInput); // Sanal klavye (yalnızca harfler, DEL, GERİ, TAMAM) var isCaps = true; var maxLen = 8; var keyboardRows = [["E", "V", "E", "T"], ["DEL", "GERI", "TAMAM"]]; var keyW = 170, keyH = 170, keyGap = 20; var kbStartX = (900 - (4 * keyW + 3 * keyGap)) / 2; var kbStartY = 320; for (var row = 0; row < keyboardRows.length; row++) { for (var col = 0; col < keyboardRows[row].length; col++) { (function (row, col) { var k = keyboardRows[row][col]; var isWideKey = k === "GERI" || k === "TAMAM"; var thisKeyW = isWideKey ? 360 : keyW; var thisKeyH = keyH; var keyBtn = new Container(); keyBtn.attachAsset('klavyeTusuGorseli', { anchorX: 0.5, anchorY: 0.5, width: thisKeyW, height: thisKeyH }); var labelText = ""; if (k === "DEL") { labelText = "Sil"; } else if (k === "GERI") { labelText = "Geri"; } else if (k === "TAMAM") { labelText = "Tamam"; } else { labelText = k; } var keyTxt = new Text2(labelText, { size: 40, fill: "#fff" }); keyBtn.label = keyTxt; keyTxt.anchor.set(0.5, 0.5); keyBtn.addChild(keyTxt); // Konumlandırma var sumW = 0; if (row === 1) { for (var c = 0; c < col; c++) { sumW += keyboardRows[row][c] === "GERI" || keyboardRows[row][c] === "TAMAM" ? 360 + keyGap : keyW + keyGap; } keyBtn.x = kbStartX + sumW + thisKeyW / 2; } else { keyBtn.x = kbStartX + col * (keyW + keyGap) + thisKeyW / 2; } keyBtn.y = kbStartY + row * (keyH + keyGap) + thisKeyH / 2; keyBtn.interactive = true; keyBtn.down = function () { var klavyeTusunaBasmaSesi = LK.getSound && LK.getSound('klavyeTusunaBasmaSesi'); if (klavyeTusunaBasmaSesi && klavyeTusunaBasmaSesi.play) { klavyeTusunaBasmaSesi.play(); } // DEL tuşu if (k === "DEL") { resetInput.text = resetInput.text.slice(0, -1); resetInput.setText(resetInput.text); return; } // GERİ tuşu if (k === "GERI") { if (playerNameDialog) { playerNameDialog.destroy(); playerNameDialog = null; } return; } // TAMAM tuşu if (k === "TAMAM") { var val = resetInput.text.trim(); if (val.toLocaleUpperCase('tr-TR') === "EVET") { // Tüm verileri sıfırla storage.playerName = null; storage.totalGames = 0; storage.winGames = 0; storage.zarStats = Object.assign({}, defaultZarStats); zarStats = storage.zarStats; // global zarStats referansını da güncelle refreshZarStatsTxt(); // görseli de hemen güncelle storage.tempGameState = null; storage.level = 1; // Seviye de sıfırlansın if (window.zarStatsTxt) { window.zarStatsTxt.setText("zar2 = 0 zar3 = 0 zar4 = 0 zar5 = 0 zar6 = 0 zar1 = 0 zarJoker = 0"); } // Diğer olası veriler de burada sıfırlanabilir // Dialog'u kapat if (playerNameDialog) { playerNameDialog.destroy(); playerNameDialog = null; } // Ana menüyü güncelle (isim sorulacak) showMainMenu(); } return; } // Harf tuşları if (resetInput.text.length < maxLen && k.length === 1) { var harf = isCaps ? k.toLocaleUpperCase('tr-TR') : k.toLocaleLowerCase('tr-TR'); resetInput.text += harf; resetInput.setText(resetInput.text); } }; keyBtn._isKeyBtn = true; keyBtn._row = row; keyBtn._col = col; playerNameDialog.addChild(keyBtn); })(row, col); } } // Ekrana ekle game.addChild(playerNameDialog); } // Oyuncu adı giriş penceresini göster function showPlayerNameDialog(onComplete) { if (playerNameDialog) { playerNameDialog.destroy(); playerNameDialog = null; } playerNameDialog = new Container(); playerNameDialog.width = 900; playerNameDialog.height = 600; playerNameDialog.x = W / 2 - 450; playerNameDialog.y = H / 2 - 300; // Arkaplan kutusu var bg = LK.getAsset('loadingBgRed', { anchorX: 0, anchorY: 0, color: 0x222222 }); playerNameDialog.addChild(bg); // Başlık var title = new Text2("Oyuncu Adı", { size: 80, fill: "#fff" }); title.anchor.set(0.5, 0); title.x = 450; title.y = 40; playerNameDialog.addChild(title); // Oyuncu adı başlığının hemen altına, 15px aşağıda gösterilecek şekilde input kutusu ve yazı var playerNameInput = new Text2("", { size: 80, fill: "#fff", background: "#444", padding: 24 }); playerNameInput.anchor.set(0.5, 0); // Oyuncu Adı başlığının y'si 40, yüksekliği 80. 15px aşağıda olacak şekilde: playerNameInput.x = 450; playerNameInput.y = 40 + 80 + 15; // title.y + title.height + 15 playerNameInput.interactive = true; playerNameInput.text = ""; playerNameDialog.addChild(playerNameInput); // --- Sanal klavye: çoklu karakter, boşluk, caps lock desteği ve özel arkaplanlar --- var isCaps = true; var maxLen = 24; // Klavye tuşları ve ek fonksiyon tuşları aynı sırada olacak şekilde var keyboardRows = [["A", "B", "C", "Ç", "D", "E", "F", "G", "Ğ"], ["H", "I", "İ", "J", "K", "L", "M", "N", "O"], ["Ö", "P", "R", "S", "Ş", "T", "U", "Ü", "V"], ["Y", "Z", "SPACE", "DEL", "CAPS", "GERI", "TAMAM"]]; // Klavye arkaplanı var keyboardBg = LK.getAsset('klavyeArkaplani', { anchorX: 0, anchorY: 0, x: -415, y: 300 }); playerNameDialog.addChild(keyboardBg); // Tuş boyutları ve konumlar var keyW = 170, keyH = 170, keyGap = 20; var keysPerRow = keyboardRows[0].length; // 9 var kbStartX = (900 - (keysPerRow * keyW + (keysPerRow - 1) * keyGap)) / 2; var kbStartY = 320; // Tuşları sırayla çiz for (var row = 0; row < keyboardRows.length; row++) { for (var col = 0; col < keyboardRows[row].length; col++) { (function (row, col) { var k = keyboardRows[row][col]; // GERI ve TAMAM tuşları için özel boyut var isWideKey = k === "GERI" || k === "TAMAM"; var thisKeyW = isWideKey ? 360 : keyW; var thisKeyH = keyH; var keyBtn = new Container(); // Tüm tuşlar aynı görselde, sadece label farklı keyBtn.attachAsset('klavyeTusuGorseli', { anchorX: 0.5, anchorY: 0.5, width: thisKeyW, height: thisKeyH }); // Label var labelText = ""; if (k === "SPACE") { labelText = "Boşluk"; } else if (k === "DEL") { labelText = "Sil"; } else if (k === "CAPS") { labelText = isCaps ? "Caps: A" : "Caps: a"; } else if (k === "GERI") { labelText = "Geri"; } else if (k === "TAMAM") { labelText = "Tamam"; } else { labelText = isCaps ? k : k.toLowerCase(); } var keyTxt = new Text2(labelText, { size: 40, fill: "#fff" }); keyBtn.label = keyTxt; // <-- etiket referansı keyTxt.anchor.set(0.5, 0.5); keyBtn.addChild(keyTxt); // Konumlandırma // GERI ve TAMAM tuşları için x pozisyonunu ayarlamak gerekiyor var xOffset = 0; if (isWideKey) { // GERI ve TAMAM tuşları son satırda, 3. ve 4. sütun // 4. satırda: ["Y", "Z", "SPACE", "DEL", "CAPS", "GERI", "TAMAM"] // GERI: col==5, TAMAM: col==6 // 5. ve 6. tuşun başı, önceki tuşların toplam genişliği + gap'leri kadar sağda olmalı // 0-4 arası normal, 5 ve 6 geniş // 0-4: keyW, 5-6: 260 // GERI'nin x'i: kbStartX + (5 * (keyW + keyGap)) + 260/2 + (col-5)*((260-keyW)/2) // TAMAM'ın x'i: kbStartX + (5 * (keyW + keyGap)) + (1 * (260 + keyGap)) + 260/2 // Hesaplamayı daha basit yapalım: // Her tuşun başı: kbStartX + sum(width+gap) + width/2 // 0-4: keyW, 5-6: 260 var sumW = 0; for (var c = 0; c < col; c++) { if (keyboardRows[row][c] === "GERI" || keyboardRows[row][c] === "TAMAM") { sumW += 360 + keyGap; } else { sumW += keyW + keyGap; } } keyBtn.x = kbStartX + sumW + thisKeyW / 2; } else { keyBtn.x = kbStartX + col * (keyW + keyGap) + thisKeyW / 2; } keyBtn.y = kbStartY + row * (keyH + keyGap) + thisKeyH / 2; keyBtn.interactive = true; keyBtn.down = function () { var klavyeTusunaBasmaSesi = LK.getSound && LK.getSound('klavyeTusunaBasmaSesi'); if (klavyeTusunaBasmaSesi && klavyeTusunaBasmaSesi.play) { klavyeTusunaBasmaSesi.play(); } // DEL tuşu if (k === "DEL") { playerNameInput.text = playerNameInput.text.slice(0, -1); playerNameInput.setText(playerNameInput.text); return; } // SPACE tuşu if (k === "SPACE") { if (playerNameInput.text.length < maxLen) { playerNameInput.text = playerNameInput.text + " "; playerNameInput.setText(playerNameInput.text); } return; } // CAPS tuşu if (k === "CAPS") { isCaps = !isCaps; playerNameDialog.children.forEach(function (btn) { if (!btn._isKeyBtn || !btn.label) { return; } var code = keyboardRows[btn._row][btn._col]; if (code === "CAPS") { btn.label.setText(isCaps ? "Caps: A" : "Caps: a"); } else if (code.length === 1) { // Harf tuşu btn.label.setText(isCaps ? code.toLocaleUpperCase("tr-TR") : code.toLocaleLowerCase("tr-TR")); } }); return; } // GERİ tuşu if (k === "GERI") { if (playerNameDialog) { playerNameDialog.destroy(); playerNameDialog = null; } return; } // TAMAM tuşu if (k === "TAMAM") { var name = playerNameInput.text.trim(); if (name.length < 2) { return; } playerName = name; storage.playerName = name; if (playerNameDialog) { playerNameDialog.destroy(); playerNameDialog = null; } if (typeof onComplete === "function") { onComplete(); } return; } // Harf tuşları if (playerNameInput.text.length < maxLen && k.length === 1) { var harf = isCaps ? k.toLocaleUpperCase('tr-TR') // büyük harf modu : k.toLocaleLowerCase('tr-TR'); // küçük harf modu playerNameInput.text += harf; playerNameInput.setText(playerNameInput.text); } }; // Tuşun tipini sakla (caps güncellemesi için) keyBtn._isKeyBtn = true; keyBtn._row = row; keyBtn._col = col; playerNameDialog.addChild(keyBtn); })(row, col); } } // Ekrana ekle game.addChild(playerNameDialog); } // Ana Menü Ekranını Göster function showMainMenu() { // Temizle if (mainMenuContainer) { mainMenuContainer.destroy(); mainMenuContainer = null; } if (gameOverContainer) { gameOverContainer.destroy(); gameOverContainer = null; } // Oyun alanını temizle if (diceGroup) { diceGroup.destroy(); diceGroup = null; } if (selectedDiceGroup) { selectedDiceGroup.destroy(); selectedDiceGroup = null; } dice = []; selectedDiceIdx = []; // Skor tablosunu gizle for (var i = 0; i < scoreTableRows.length; i++) { if (scoreTableRows[i]) { scoreTableRows[i].visible = false; } } if (turnTxt) { turnTxt.visible = false; } // Ana menüde puan tablosu ve açıklama görünmesin if (window._farkleScoreTable) { window._farkleScoreTable.visible = false; } if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.visible = false; } // Zar istatistik satırını gizle (sadece oyun ekranında görünür) if (window.zarStatsRow) { window.zarStatsRow.visible = false; } // --- Kazanma Oranı etiketi --- if (!window.winRateTxt) { // daha önce hiç oluşturulmamışsa burada yarat window.winRateTxt = new Text2("", { size: 48, fill: '#ffe066', fontWeight: 'bold' }); window.winRateTxt.anchor.set(0.5, 0); LK.gui.top.addChild(window.winRateTxt); } // değerleri güncelle ve görünür yap var lang = getLanguage(); var t = (typeof LANGS === "undefined" ? "undefined" : _typeof5(LANGS)) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0; var winGames = typeof storage.winGames === "number" ? storage.winGames : 0; var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1; var oran = totalGames > 0 ? lang === "tr" ? Math.round(winGames / totalGames * 100) + "%" : Math.round(winGames / totalGames * 100) + "%" : lang === "tr" ? "∅" : "∅"; var oyunStr = totalGames > 0 ? totalGames : "0"; if (t && t.winRate && t.matchCount && t.level) { window.winRateTxt.setText(t.winRate + ": " + oran + " | " + t.matchCount + ": " + oyunStr + " | " + t.level + ": " + level); } else { // Fallback to Turkish if t is missing or incomplete window.winRateTxt.setText("Zafer Oranı: " + oran + " | Maç Sayısı: " + oyunStr + " | Seviye: " + level); } window.winRateTxt.x = 0; window.winRateTxt.y = 20; window.winRateTxt.visible = true; // Butonları pasifleştir rollBtn.visible = false; bankBtn.visible = false; if (typeof passBtn !== "undefined") { passBtn.visible = false; } // Remove oyun ekranı arkaplanı if exists if (game._oyunBg) { game._oyunBg.destroy(); game._oyunBg = null; } // Ana Menü Container mainMenuContainer = new Container(); mainMenuContainer.width = W; mainMenuContainer.height = H; // Arkaplan (anaMenuEkraniArkaplani) var bg = LK.getAsset('anaMenuEkraniArkaplani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: W, height: H }); mainMenuContainer.addChild(bg); // Müzik sadece loading ekranı kalkınca başlatılacak, burada tekrar başlatılmıyor // "Oyunu Başlat" Butonu var startBtn = new Container(); startBtn.attachAsset('oyunuBaslatButonuGorseli', { anchorX: 0.5, anchorY: 0.5 }); var startTxt = new Text2('Oyunu Başlat', { size: 124, fill: '#fff' }); startTxt.anchor.set(0.5, 0.5); startTxt.y = 40; startBtn.addChild(startTxt); startBtn.x = W / 2; startBtn.y = H / 2 - 230; startBtn.interactive = true; startBtn.down = function () { var oyunuBaslatButonuSesi = LK.getSound && LK.getSound('oyunuBaslatButonuSesi'); if (oyunuBaslatButonuSesi && oyunuBaslatButonuSesi.play) { oyunuBaslatButonuSesi.play(); } // Oyuncu adı yoksa önce sor, varsa direkt başlat if (!storage.playerName) { showPlayerNameDialog(function () { hideMainMenu(); startGame(); }); } else { playerName = storage.playerName; hideMainMenu(); startGame(); } }; mainMenuContainer.addChild(startBtn); // --- HESABI SIFIRLA BUTONU --- // Buton görseli ve metni var sifirlaBtn = new Container(); sifirlaBtn.attachAsset('tamamButonuGorseli', { anchorX: 0.5, anchorY: 0.5 }); var sifirlaTxt = new Text2('', { size: 124, fill: '#fff' }); sifirlaTxt.anchor.set(0.5, 0.5); sifirlaTxt.y = 40; sifirlaBtn.addChild(sifirlaTxt); // Konum: Başlat butonunun hemen altında, arada 80px boşluk sifirlaBtn.x = W / 2; sifirlaBtn.y = H / 2 + 230; sifirlaBtn.interactive = true; sifirlaBtn.down = function () { var hesabiSifirlaButonuSesi = LK.getSound && LK.getSound('hesabiSifirlaButonuSesi'); if (hesabiSifirlaButonuSesi && hesabiSifirlaButonuSesi.play) { hesabiSifirlaButonuSesi.play(); } // Sıfırlama onay penceresini göster showResetAccountDialog(); }; mainMenuContainer.addChild(sifirlaBtn); // --- DİLLER BUTONU --- // Diller butonunu Hesabı Sıfırla butonunun hemen altına ekle var langBtn = new Container(); langBtn.attachAsset('dillerButonuGorseli', { anchorX: 0.5, anchorY: 0.5 }); var langTxt = new Text2('', { size: 124, fill: '#fff' }); langTxt.anchor.set(0.5, 0.5); langTxt.y = 40; langBtn.addChild(langTxt); langBtn.x = W / 2; langBtn.y = sifirlaBtn.y + 460; langBtn.interactive = true; mainMenuContainer.addChild(langBtn); // Dil seçme penceresi referansı var langDialog = null; // Dil seçme penceresini gösteren fonksiyon function showLangDialog() { if (langDialog) { langDialog.destroy(); langDialog = null; } langDialog = new Container(); langDialog.x = W / 2; langDialog.y = H / 2 - 300; // Arkaplan kutusu var bg = LK.getAsset('loadingBgRed2', { anchorX: 0.5, anchorY: 0, color: 0x222222 }); langDialog.addChild(bg); // Başlık var info = new Text2('', { size: 106, fill: 0xFFE066 }); info.anchor.set(0.5, 0); info.x = 0; info.y = 88; langDialog.addChild(info); // Türkçe butonu var trBtn = new Container(); trBtn.attachAsset('turkceDilButonuGorseli', { anchorX: 0.5, anchorY: 0.5 }); var trTxt = new Text2('Türkçe', { size: 64, fill: '#fff' }); trTxt.anchor.set(0.5, 0.5); trTxt.y = 0.5; trBtn.addChild(trTxt); trBtn.x = -196; trBtn.y = 320; trBtn.interactive = true; trBtn.down = function () { setLanguage('tr'); if (langDialog) { langDialog.destroy(); langDialog = null; } updateAllTexts(); }; langDialog.addChild(trBtn); // İngilizce butonu var enBtn = new Container(); enBtn.attachAsset('ingilizceDilButonuGorseli', { anchorX: 0.5, anchorY: 0.5 }); var enTxt = new Text2('English', { size: 64, fill: '#fff' }); enTxt.anchor.set(0.5, 0.5); enTxt.y = 0.5; enBtn.addChild(enTxt); enBtn.x = 200; enBtn.y = 320; enBtn.interactive = true; enBtn.down = function () { setLanguage('en'); if (langDialog) { langDialog.destroy(); langDialog = null; } updateAllTexts(); }; langDialog.addChild(enBtn); game.addChild(langDialog); // Başlık ve buton yazılarını güncelle updateLangDialogTexts(); } // Diller butonuna tıklanınca pencereyi aç langBtn.down = function () { showLangDialog(); }; // --- Dil yönetimi --- // Desteklenen diller ve çeviriler - Define globally before any usage var LANGS = { tr: { start: "Oyunu Başlat", reset: "Hesabı Sıfırla", lang: "Diller", langTitle: "Dil Seç", turkce: "Türkçe", ingilizce: "English", menu: "Ana Menüye Dön", win: "Kazandın!", lose: "Kaybettin...", pass: "PAS", "continue": "DEVAM", bank: "TAMAM", resetConfirm: "Bu işlemden emin misin?", playerName: "Oyuncu Adı", ok: "Tamam", back: "Geri", "delete": "Sil", caps: "Caps: A", caps2: "Caps: a", info: "3'ten sonraki her ilave zar değerini iki katına çıkarır.", bust: "İflas!", turn1: "Sıra: 1. Oyuncuda", turn2: "Sıra: 2. Oyuncuda", selectedScore: "Seçilen Skor", tempScore: "Geçici Skor", mainScore: "Ana Skor", target: "Hedef", ai: "Yapay Zeka", matchCount: "Maç Sayısı", winRate: "Zafer Oranı", level: "Seviye", earlyAccess: "Erken Erişim", instagram: "Instagram: ugurcanyardim_", loading: "Yükleniyor...", loadingInfo: "En iyi oyun deneyimi için lütfen oyunun grafik ve ses kaynakları tamamen yüklenene kadar bekleyin. Unutmayın ki insanların %99'u büyük kazanamadan hemen önce oyunu bırakıyor! %1'e girebilecek misiniz?" }, en: { start: "Start Game", reset: "Reset Account", lang: "Languages", langTitle: "Select Language", turkce: "Turkish", ingilizce: "English", menu: "Return to Menu", win: "You Win!", lose: "You Lose...", pass: "PASS", "continue": "ROLL", bank: "BANK", resetConfirm: "Are you sure?", playerName: "Player Name", ok: "OK", back: "Back", "delete": "Delete", caps: "Caps: A", caps2: "Caps: a", info: "Each extra die after 3 multiplies the value by two.", bust: "Bust!", turn1: "Turn: Player 1", turn2: "Turn: Player 2", selectedScore: "Selected Score", tempScore: "Temp Score", mainScore: "Main Score", target: "Target", ai: "AI", matchCount: "Matches", winRate: "Win Rate", level: "Level", earlyAccess: "Early Access", instagram: "Instagram: ugurcanyardim_", loading: "Loading...", loadingInfo: "For the best experience, please wait until all graphics and sounds are loaded. Remember, 99% of people quit just before a big win! Will you be the 1%?" } }; // Seçili dili storage'dan al, yoksa Türkçe function getLanguage() { // Defensive: check LANGS exists and has property if (typeof storage !== "undefined" && storage && typeof storage.lang === "string" && _typeof4(LANGS) === "object" && LANGS && Object.prototype.hasOwnProperty.call(LANGS, storage.lang)) { return storage.lang; } return "tr"; } function setLanguage(lang) { if (LANGS[lang]) { storage.lang = lang; } } // Tüm yazıları güncelleyen fonksiyon function updateAllTexts() { var lang = getLanguage(); var t = _typeof5(LANGS) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; // Ana Menü if (typeof startTxt !== "undefined") { startTxt.setText(t.start); } if (typeof sifirlaTxt !== "undefined") { sifirlaTxt.setText(t.reset); } if (typeof langTxt !== "undefined") { langTxt.setText(t.lang); } // Diller penceresi açıksa başlık ve butonlar updateLangDialogTexts(); // Skor tablosu ve üst yazılar if (scoreTableRows && scoreTableRows[0]) { var playerNameDisplay = typeof playerName === "string" && playerName.length > 0 ? playerName : lang === "tr" ? "1. Oyuncu" : "Player 1"; scoreTableRows[0].setText(playerNameDisplay + " | " + t.target + " | " + t.ai); } if (scoreTableRows && scoreTableRows[1]) { var dynamicTarget = 1000 + ((typeof storage.level === "number" ? storage.level : 1) - 1) * 250; scoreTableRows[1].setText(t.mainScore + ": " + scores[PLAYER] + " | " + dynamicTarget + " | " + t.mainScore + ": " + scores[NPC]); } if (scoreTableRows && scoreTableRows[2]) { scoreTableRows[2].setText(t.tempScore + ": " + tempScores[PLAYER] + " | Tur: " + turnNumber + " | " + t.tempScore + ": " + tempScores[NPC]); } if (scoreTableRows && scoreTableRows[3]) { var liveSelectedScorePlayer = 0; var liveSelectedScoreNPC = 0; if (current === PLAYER && selectedDiceIdx.length > 0) { var selValsLive = selectedDiceIdx.map(function (i) { return dice[i].value; }); if (isValidSelection(selValsLive)) { liveSelectedScorePlayer = calcScoreFarkle(selValsLive).score; } } if (current === NPC && dice.length > 0) { var selValsLiveNPC = []; for (var i = 0; i < dice.length; i++) { if (dice[i].selected) { selValsLiveNPC.push(dice[i].value); } } if (selValsLiveNPC.length > 0 && isValidSelection(selValsLiveNPC)) { liveSelectedScoreNPC = calcScoreFarkle(selValsLiveNPC).score; } } scoreTableRows[3].setText(t.selectedScore + ": " + (current === PLAYER ? liveSelectedScorePlayer : selectedScores[PLAYER]) + " | Seçilen | " + t.selectedScore + ": " + (current === NPC ? liveSelectedScoreNPC : selectedScores[NPC])); } if (typeof turnTxt !== "undefined") { turnTxt.setText(current === PLAYER ? t.turn1 : t.turn2); } // Zar istatistik satırı, info yazısı if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.setText(t.info); } // Oyun sonu ekranı if (typeof gameOverContainer !== "undefined" && gameOverContainer && gameOverContainer.children) { for (var i = 0; i < gameOverContainer.children.length; i++) { var ch = gameOverContainer.children[i]; if (ch instanceof Text2 && (ch.size === 200 || ch.size === 180)) { // Sonuç yazısı if (current === PLAYER) { ch.setText(t.win); } else if (current === NPC) { ch.setText(t.lose); } } if (ch instanceof Container && ch.children && ch.children.length > 0) { for (var j = 0; j < ch.children.length; j++) { var sub = ch.children[j]; if (sub instanceof Text2 && sub.text && (sub.text === "Ana Menüye Dön" || sub.text === "Return to Menu")) { sub.setText(t.menu); } } } } } // Ana menüdeki menü butonları if (typeof menuTxt !== "undefined") { menuTxt.setText(t.menu); } // Butonlar (oyun ekranı) if (typeof passTxt !== "undefined") { passTxt.setText(t.pass); } if (typeof rollTxt !== "undefined") { rollTxt.setText(t["continue"]); } if (typeof bankTxt !== "undefined") { bankTxt.setText(t.bank); } // Win rate, maç sayısı, seviye if (window.winRateTxt) { var totalGames = typeof storage.totalGames === "number" ? storage.totalGames : 0; var winGames = typeof storage.winGames === "number" ? storage.winGames : 0; var level = typeof storage.level === "number" && storage.level >= 1 ? storage.level : 1; var oran = totalGames > 0 ? lang === "tr" ? Math.round(winGames / totalGames * 100) + "%" : Math.round(winGames / totalGames * 100) + "%" : lang === "tr" ? "∅" : "∅"; var oyunStr = totalGames > 0 ? totalGames : "0"; window.winRateTxt.setText(t.winRate + ": " + oran + " | " + t.matchCount + ": " + oyunStr + " | " + t.level + ": " + level); } // Instagram ve erken erişim if (window.instaText) { window.instaText.setText(t.instagram); } if (window.betaText) { window.betaText.setText(t.earlyAccess); } // Yükleme ekranı if (typeof loadingContainer !== "undefined" && loadingContainer && loadingContainer.children) { for (var i = 0; i < loadingContainer.children.length; i++) { var ch = loadingContainer.children[i]; if (ch instanceof Text2 && ch.size === 90) { ch.setText(t.loading); } if (ch instanceof Text2 && ch.size === 36) { ch.setText(t.loadingInfo); } } } } // Diller penceresindeki başlık ve butonları güncelle function updateLangDialogTexts() { if (!langDialog) { return; } var lang = getLanguage(); var t = _typeof5(LANGS) === "object" && LANGS && LANGS[lang] ? LANGS[lang] : {}; for (var i = 0; i < langDialog.children.length; i++) { var ch = langDialog.children[i]; if (ch instanceof Text2) { ch.setText(t.langTitle); } if (ch instanceof Container && ch.children && ch.children.length > 0) { for (var j = 0; j < ch.children.length; j++) { var sub = ch.children[j]; if (sub instanceof Text2) { if (sub.text === "Türkçe" || sub.text === "Turkish") { sub.setText(t.turkce); } if (sub.text === "English") { sub.setText(t.ingilizce); } } } } } } // Oyun başında dili uygula updateAllTexts(); game.addChild(mainMenuContainer); // --- Instagram ve Erken Erişim Yazıları (sadece ana menüde) --- if (!window.instaText) { // Instagram: ugurcanyardim_ var instaText = new Text2("Instagram: ugurcanyardim_", { size: 64, fill: 0xFF0000, // kırmızı fontWeight: "bold" }); instaText.anchor.set(0.5, 0); window.instaText = instaText; // Beta text var betaText = new Text2("Erken Erişim", { size: 64, fill: 0xFFE066, // sarı fontWeight: "bold" }); betaText.anchor.set(0, 0); // left-top window.betaText = betaText; } // Pozisyonları langBtn'a göre ayarla // langBtn yoksa, referans noktası olarak startBtn kullan var refBtn = typeof langBtn !== "undefined" && langBtn ? langBtn : startBtn; window.instaText.x = refBtn.x - 586; window.instaText.y = refBtn.y + 1500; window.betaText.x = window.instaText.x + 1194; window.betaText.y = window.instaText.y; // Sadece ana menüde göster window.instaText.visible = true; window.betaText.visible = true; mainMenuContainer.addChild(window.instaText); mainMenuContainer.addChild(window.betaText); clearGameState(); // --- Konfeti efektini ve parçacıklarını temizle (ana menüye dönünce) --- if (confettiInterval) { LK.clearInterval(confettiInterval); confettiInterval = null; } for (var i = 0; i < confettiParticles.length; i++) { if (confettiParticles[i] && confettiParticles[i].parent) { confettiParticles[i].parent.removeChild(confettiParticles[i]); } } confettiParticles = []; // Olası update fonksiyonunu da temizle if (gameOverContainer && gameOverContainer.update) { gameOverContainer.update = null; } } // Ana Menü Ekranını Gizle function hideMainMenu() { if (mainMenuContainer) { mainMenuContainer.destroy(); mainMenuContainer = null; } // Skor tablosunu göster for (var i = 0; i < scoreTableRows.length; i++) { if (scoreTableRows[i]) { scoreTableRows[i].visible = true; } } if (turnTxt) { turnTxt.visible = true; } // Oyun ekranına dönünce puan tablosunu ve açıklamayı tekrar göster if (window._farkleScoreTable) { window._farkleScoreTable.visible = true; } if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.visible = true; } // Butonları göster rollBtn.visible = true; bankBtn.visible = true; if (typeof passBtn !== "undefined") { passBtn.visible = true; } // Zar istatistik satırını göster (sadece oyun ekranında) if (window.zarStatsRow) { window.zarStatsRow.visible = true; } } // Oyun Sonu Ekranını Göster function showGameOverScreen(winnerText) { // Temizle if (gameOverContainer) { gameOverContainer.destroy(); gameOverContainer = null; } if (mainMenuContainer) { mainMenuContainer.destroy(); mainMenuContainer = null; } // Oyun alanını temizle if (diceGroup) { diceGroup.destroy(); diceGroup = null; } if (selectedDiceGroup) { selectedDiceGroup.destroy(); selectedDiceGroup = null; } dice = []; selectedDiceIdx = []; // Skor tablosunu gizle for (var i = 0; i < scoreTableRows.length; i++) { if (scoreTableRows[i]) { scoreTableRows[i].visible = false; } } if (turnTxt) { turnTxt.visible = false; } // Oyun sonu ekranında puan tablosu görünmesin, sadece oyun ekranında görünsün if (window._farkleScoreTable) { window._farkleScoreTable.visible = false; } if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.visible = false; } // Zar istatistik satırını gizle (sadece oyun ekranında görünür) if (window.zarStatsRow) { window.zarStatsRow.visible = false; } // Kazanma oranı ve oyun sayısı yazısı oyun sonu ekranında da görünür olsun if (window.winRateTxt) { window.winRateTxt.visible = true; window.winRateTxt.x = 0; window.winRateTxt.y = 20; } // Butonları pasifleştir rollBtn.visible = false; bankBtn.visible = false; if (typeof passBtn !== "undefined") { passBtn.visible = false; } // Remove oyun ekranı arkaplanı if exists if (game._oyunBg) { game._oyunBg.destroy(); game._oyunBg = null; } clearGameState(); // Oyun Sonu Container gameOverContainer = new Container(); gameOverContainer.width = W; gameOverContainer.height = H; // Arkaplan (oyunSonuEkraniArkaplani) var bg = LK.getAsset('oyunSonuEkraniArkaplani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: W, height: H }); gameOverContainer.addChild(bg); // Oyun sonunda kazanan/kaybeden SFX çal if (typeof current !== "undefined") { if (current === PLAYER) { var senKazandinSesi = LK.getSound && LK.getSound('senKazandinSesi'); if (senKazandinSesi && senKazandinSesi.play) { senKazandinSesi.play(); } } else if (current === NPC) { var kaybettinSesi = LK.getSound && LK.getSound('kaybettinSesi'); if (kaybettinSesi && kaybettinSesi.play) { kaybettinSesi.play(); } } } // Müzik sadece loading ekranı kalkınca başlatılacak, burada tekrar başlatılmıyor // Kazanan/Kaybeden Metni var resultTxt = new Text2(winnerText || 'Oyun Bitti', { size: 200, fill: '#fff' }); resultTxt.anchor.set(0.5, 0.5); resultTxt.x = W / 2; resultTxt.y = H / 2 - 350; gameOverContainer.addChild(resultTxt); // "Ana Menüye Dön" Butonu var menuBtn = new Container(); menuBtn.attachAsset('anaMenuyeDonButonuGorseli', { anchorX: 0.5, anchorY: 0.5 }); var menuTxt = new Text2('Ana Menüye Dön', { size: 100, fill: '#fff' }); menuTxt.anchor.set(0.5, 0.5); menuTxt.y = 40; menuBtn.addChild(menuTxt); menuBtn.x = W / 2; menuBtn.y = H / 2; menuBtn.interactive = true; menuBtn.down = function () { var anaMenuyeDonButonuSesi = LK.getSound && LK.getSound('anaMenuyeDonButonuSesi'); if (anaMenuyeDonButonuSesi && anaMenuyeDonButonuSesi.play) { anaMenuyeDonButonuSesi.play(); } hideGameOverScreen(); showMainMenu(); }; gameOverContainer.addChild(menuBtn); game.addChild(gameOverContainer); // --- Konfeti Efekti: Sadece oyuncu kazandıysa başlat --- if (typeof current !== "undefined" && current === PLAYER) { // Önce varsa eski konfeti efektini temizle if (confettiInterval) { LK.clearInterval(confettiInterval); confettiInterval = null; } // Tüm eski konfeti parçacıklarını temizle for (var i = 0; i < confettiParticles.length; i++) { if (confettiParticles[i] && confettiParticles[i].parent) { confettiParticles[i].parent.removeChild(confettiParticles[i]); } } confettiParticles = []; // Konfeti efektini başlat: her 80ms'de yeni parçacık ekle confettiInterval = LK.setInterval(function () { // Her seferinde 2-4 yeni konfeti ekle var count = 2 + Math.floor(Math.random() * 3); for (var j = 0; j < count; j++) { var confetti = new ConfettiParticle(); gameOverContainer.addChild(confetti); confettiParticles.push(confetti); } }, 80); // Konfeti parçacıklarını güncellemek için gameOverContainer.update fonksiyonu gameOverContainer.update = function () { // Tüm konfeti parçacıklarını güncelle for (var i = confettiParticles.length - 1; i >= 0; i--) { var c = confettiParticles[i]; if (c && !c._destroyed && typeof c.update === "function") { c.update(); } // Yok edilenleri diziden çıkar if (c._destroyed) { confettiParticles.splice(i, 1); } } }; } else { // Kazanmadıysan konfeti efektini başlatma, varsa temizle if (confettiInterval) { LK.clearInterval(confettiInterval); confettiInterval = null; } for (var i = 0; i < confettiParticles.length; i++) { if (confettiParticles[i] && confettiParticles[i].parent) { confettiParticles[i].parent.removeChild(confettiParticles[i]); } } confettiParticles = []; if (gameOverContainer.update) { gameOverContainer.update = null; } } } // Oyun Sonu Ekranını Gizle function hideGameOverScreen() { if (gameOverContainer) { gameOverContainer.destroy(); gameOverContainer = null; } // Skor tablosunu göster for (var i = 0; i < scoreTableRows.length; i++) { if (scoreTableRows[i]) { scoreTableRows[i].visible = true; } } if (turnTxt) { turnTxt.visible = true; } // Oyun ekranına dönünce puan tablosunu tekrar göster if (window._farkleScoreTable) { window._farkleScoreTable.visible = true; } if (window._farkleScoreInfoTxt) { window._farkleScoreInfoTxt.visible = true; } // Butonları göster rollBtn.visible = true; bankBtn.visible = true; if (typeof passBtn !== "undefined") { passBtn.visible = true; } // Zar istatistik satırını göster (sadece oyun ekranında) if (window.zarStatsRow) { window.zarStatsRow.visible = true; } } // --- Kazanan ekranı override --- // Yükleme ekranı için sınıf ve gösterme fonksiyonu var loadingContainer = null; var loadingTimeout = null; // Tween plugin import // Yükleme ekranını göster function showLoadingScreen() { // First, create the main menu in the background so resources can load showMainMenu(); // Hide winRateTxt during loading screen if (window.winRateTxt) { window.winRateTxt.visible = false; } // Müzik yükleme ekranında başlamasın, sadece loading kalkınca başlatacağız // (Burada playMusic çağrısı kaldırıldı) // Temizle if (loadingContainer) { loadingContainer.destroy(); loadingContainer = null; } loadingContainer = new Container(); loadingContainer.width = W; loadingContainer.height = H; // Yükleme ekranı arkaplanı var bg = LK.getAsset('yuklemeEkraniArkaplani', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: W, height: H }); loadingContainer.addChild(bg); // Novatek logosu (ortada üstte) var logo = LK.getAsset('novatekLogosu', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1050 }); loadingContainer.addChild(logo); // "Loading..." yazısı var loadingTxt = new Text2('Yükleniyor...', { size: 90, fill: '#fff' }); loadingTxt.anchor.set(0.5, 0.5); loadingTxt.x = 1024; loadingTxt.y = 1366; loadingContainer.addChild(loadingTxt); // Alt açıklama yazısı var infoTxt = new Text2("En iyi oyun deneyimi için lütfen oyunun grafik ve ses kaynakları tamamen yüklenene kadar bekleyin. Unutmayın ki insanların %99'u büyük kazanamadan hemen önce oyunu bırakıyor! %1'e girebilecek misiniz?", { size: 36, fill: '#fff', wordWrap: true, wordWrapWidth: 1800, align: 'center' }); infoTxt.anchor.set(0.5, 0); infoTxt.x = 1024; infoTxt.y = 1460; loadingContainer.addChild(infoTxt); // Dönen yükleme çubuğu var spinner = LK.getAsset('yuklemeCubugu', { anchorX: 0.5, anchorY: 0.5, x: W / 2, y: infoTxt.y + infoTxt.height + 120 }); loadingContainer.addChild(spinner); // Spinner animasyonu (dönme) spinner.rotation = 0; var _spinTween = function spinTween() { tween(spinner, { rotation: spinner.rotation + Math.PI * 2 }, { duration: 1200, easing: tween.linear, onFinish: _spinTween }); }; _spinTween(); // Add loading screen on top of main menu game.addChild(loadingContainer); // 10 saniye sonra loading ekranını kaldır (ana menü zaten gösteriliyor) loadingTimeout = LK.setTimeout(function () { if (loadingContainer) { loadingContainer.destroy(); loadingContainer = null; } // Show winRateTxt after loading screen is removed if (window.winRateTxt) { window.winRateTxt.visible = true; } // Ana menü zaten gösteriliyor, sadece loading overlay'ini kaldırıyoruz // Müzik burada başlatılır, sadece bir kez ve döngüde LK.playMusic('oyunEkraniMuzigi', { loop: true }); }, 10000); } // Oyun başında yükleme ekranını göster showLoadingScreen(); /* --- Responsive HUD --- */ if (!window._frvr_gui_resize_hooked) { window._frvr_gui_resize_hooked = true; LK.on('resize', function () { var centerX = W / 2; // 2048/2 = 1024, ekranın tam ortası for (var i = 0; i < scoreTableRows.length; i++) { if (scoreTableRows[i]) { scoreTableRows[i].x = centerX; } } if (turnTxt) { turnTxt.x = centerX; } }); } // --- Fix: Define npcBustFlow for NPC bust handling --- function npcBustFlow() { // Show red flash and 'İflas!' text for NPC bust LK.effects.flashScreen(0xff0000, 1200); var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!"; var iflasTxt = new Text2(bustText, { size: 180, fill: '#fff' }); iflasTxt.anchor.set(0.5, 0.5); iflasTxt.x = W / 2; iflasTxt.y = H / 2; iflasTxt.alpha = 1; game.addChild(iflasTxt); // Play NPC bust sound var iflasRakipSesi = LK.getSound && LK.getSound('iflasRakipSesi'); if (iflasRakipSesi && iflasRakipSesi.play) { iflasRakipSesi.play(); } LK.setTimeout(function () { tween(iflasTxt, { alpha: 0 }, { duration: 700, easing: tween.easeOut, onFinish: function onFinish() { if (iflasTxt && iflasTxt.parent) { iflasTxt.parent.removeChild(iflasTxt); } tempScores[NPC] = selectedScores[NPC] = turnScore = 0; updateHUD(); LK.setTimeout(endTurn, BUST_PASS_DELAY); } }); }, 1000); }
===================================================================
--- original.js
+++ change.js
@@ -2089,9 +2089,10 @@
if (!canMakeAnyScore(unselVals)) {
// Kırmızı ekranı daha uzun göster (ör: 1200ms)
LK.effects.flashScreen(0xff0000, 1200);
// "İflas!" yazısı ekle
- var iflasTxt = new Text2(LANGS[getLanguage()].bust, {
+ var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!";
+ var iflasTxt = new Text2(bustText, {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
@@ -2168,9 +2169,10 @@
});
// Eğer kalan zarlarla hiçbir şekilde kombinasyon yapılamıyorsa otomatik olarak turu rakibe geçir
if (!canMakeAnyScore(unselVals)) {
LK.effects.flashScreen(0xff0000, 1200);
- var iflasTxt = new Text2(LANGS[getLanguage()].bust, {
+ var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!";
+ var iflasTxt = new Text2(bustText, {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
@@ -2289,9 +2291,10 @@
if (!canMakeAnyScore(unselVals)) {
// Ekranı kırmızıya flash et
LK.effects.flashScreen(0xff0000, 1200);
// "İflas!" yazısı ekle
- var iflasTxt = new Text2(LANGS[getLanguage()].bust, {
+ var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!";
+ var iflasTxt = new Text2(bustText, {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
@@ -3374,9 +3377,9 @@
langBtn.down = function () {
showLangDialog();
};
// --- Dil yönetimi ---
- // Desteklenen diller ve çeviriler
+ // Desteklenen diller ve çeviriler - Define globally before any usage
var LANGS = {
tr: {
start: "Oyunu Başlat",
reset: "Hesabı Sıfırla",
@@ -4035,9 +4038,10 @@
// --- Fix: Define npcBustFlow for NPC bust handling ---
function npcBustFlow() {
// Show red flash and 'İflas!' text for NPC bust
LK.effects.flashScreen(0xff0000, 1200);
- var iflasTxt = new Text2(LANGS[getLanguage()].bust, {
+ var bustText = typeof LANGS !== "undefined" && LANGS && LANGS[getLanguage()] && LANGS[getLanguage()].bust ? LANGS[getLanguage()].bust : "İflas!";
+ var iflasTxt = new Text2(bustText, {
size: 180,
fill: '#fff'
});
iflasTxt.anchor.set(0.5, 0.5);
Yeşil casino masa arkaplanı. Dikdörtgen.
Casino oyunum için buton olarak kullanmalık dikdörtgen (köşeleri yumuşatılmış, edge). Yazısız.. In-Game asset. 2d. High contrast. No shadows
Bu sefer zar 1 yerine zar 2 olsun. Delik kırmızı değil siyah olsun.
Zar 2 değil 3 olsun.
Zar 4 olsun. Deliklerinin içi dolu siyah olsun.
Zar 2 değil, zar 5 olsun.
Zar 6 olsun. İçindeki deliklerin içi dolu siyah olsun.
Zar 6 değil, zar joker olsun. Yani zarın üstünde joker sembolü olsun.
Zar 4 değil, zar 1 olsun. İçi siyah değil kırmızı olsun.
Casino tarzında yatay dikdörtgen (köşeleri yumuşatılmış, edge). İçi sarı, dışında kırmızı şerit var. Sol üst köşesinde bir çift zar var. Yazısız.. In-Game asset. 2d. High contrast. No shadows. Casino
oyunEkraniMuzigi
Music
zarBirakmaSesi
Sound effect
zarSecmeSesi
Sound effect
tutVeDevamEtSesi
Sound effect
tutVeTuruSonlandirSesi
Sound effect
ilkSenBasliyorsunSesi
Sound effect
rakibinSirasiSesi
Sound effect
siraSendeSesi
Sound effect
iflasBenSesi
Sound effect
iflasRakipSesi
Sound effect
senKazandinSesi
Sound effect
kaybettinSesi
Sound effect
pasButonuSesi
Sound effect
klavyeTusunaBasmaSesi
Sound effect
oyunuBaslatButonuSesi
Sound effect
anaMenuyeDonButonuSesi
Sound effect
hesabiSifirlaButonuSesi
Sound effect
yuklemeEkraniSesi
Sound effect
ilkRakipBasliyorSesi
Sound effect